2016-05-05 12 views
0

Ich brauche wenig Hilfe beim Lesen meiner "chats" SQL-Tabelle.SQL SELECT - Chats

Säule:

Chat_ID - decimal(18, 0) primary key, inflexible-yes 

Sent_ID - decimal(18, 0) 

Receive_ID - decimal(18, 0) 

Time - datetime 

Message - nvarchar(MAX) 


Sent_ID| Receive_ID |  Time  |  Message 
-------+----------+------------------+----------------- 
    1 | 2  | 11/21/2015 10:00 | Hey! test 
-------+----------+------------------+----------------- 
    2 | 1  | 11/21/2015 10:50 | Hi! respond 
-------+----------+------------------+----------------- 
    1 | 2  | 11/21/2015 10:51 | respond 3 
-------+----------+------------------+----------------- 
    2 | 1  | 11/21/2015 11:05 | respond final 
-------+----------+------------------+----------------- 
    1 | 3  | 11/21/2015 11:51 | Message 1 
-------+----------+------------------+----------------- 
    3 | 1  | 11/21/2015 12:05 | Message 2 
-------+----------+------------------+----------------- 
    1 | 3  | 11/21/2015 12:16 | Message Final 
-------+----------+------------------+----------------- 
    4 | 1  | 11/21/2015 12:25 | New message 1 
-------+----------+------------------+----------------- 

Wie kommt man ... (letzte Nachricht mit jedem Benutzer?)

Sent_ID| Receive_ID |  Time  |  Message 
-------+----------+------------------+----------------- 
    2 | 1  | 11/21/2015 11:05 | respond final 
-------+----------+------------------+----------------- 
    1 | 3  | 11/21/2015 12:16 | Message Final 
-------+----------+------------------+----------------- 
    4 | 1  | 11/21/2015 12:25 | New message 1 
-------+----------+------------------+----------------- 

Man merkt, dass ich brauche so etwas wie: MAX (Time), WO (Sent_ID = @ Sent_ID oder Receive_ID = @ Receive_ID) in diesem Fall ........... Sent_ID = 1 ..... Receive_ID = zu vereinfachen: WHERE (Sent_ID = 1 oder Receive_ID = 1)

Danke ....

+0

Welche DBMS verwenden Sie? –

Antwort

1

Update: Ich verstehe jetzt, dass Sie die neueste Nachricht zwischen zwei Benutzern, unabhängig erhalten möchten, wenn sie gesendet oder empfangen wird. Wenn das der Fall ist, können Sie ROW_NUMBER verwenden:

ONLINE DEMO

WITH Cte AS(
    SELECT *, 
     rn = ROW_NUMBER() OVER(
        PARTITION BY 
         CASE 
          WHEN Sent_ID > Receive_ID THEN Receive_ID 
          ELSE Sent_ID 
         END, 
         CASE 
          WHEN Sent_ID > Receive_ID THEN Sent_ID 
          ELSE Receive_ID 
         END 
        ORDER BY Time DESC 
       ) 
    FROM chats 
    WHERE 
     Sent_ID = 1 
     OR Receive_ID = 1 
) 
SELECT 
    Sent_ID, Receive_ID, Time, Message 
FROM Cte 
WHERE rn = 1 

Was die obige Abfrage tut, ist die Chat-Nachrichten durch die untere ID zu partitionieren zuerst, und dann die höhere ID. Auf diese Weise stellen Sie sicher, dass Sie eine eindeutige Kombination von IDs haben.


Zuerst müssen Sie die letzte Nachricht vom Benutzer erhalten. Und die UNION es zu den letzten Nachrichten, die der Benutzer von jedem der anderen Benutzer erhalten.

SELECT c.* 
FROM chats c 
INNER JOIN (
    SELECT 
     Sent_ID, MAX(Time) AS MaxTime 
    FROM chats 
    WHERE Sent_ID = 1 
    GROUP BY Sent_ID 
) t 
    ON t.Sent_ID = c.Sent_ID 
    AND t.MaxTime = c.Time 

UNION ALL 

SELECT c.* 
FROM chats c 
INNER JOIN (
    SELECT 
     Sent_ID, MAX(Time) AS MaxTime 
    FROM chats 
    WHERE Receive_ID = 1 
    GROUP BY Sent_ID 
) t 
    ON t.Sent_ID = c.Sent_ID 
    AND t.MaxTime = c.Time 

ONLINE DEMO

+0

Ich werde das auf meiner Datenbank testen. Aber wenn ich sehe, dass deine ONLINE-DEMO nicht richtig funktioniert. Wiederhole die Spalten 1 und 3 ... Aber ich werde testen ... – Milan

+0

@Milan, Oh, ich habe dein Problem missverstanden. Bitte sehen Sie meine aktualisierte Antwort. –

+0

Vielen Dank für Ihre Antwort werde ich testen. – Milan

0

Problem ist mit Reihen sind nicht eindeutig zu sein, wie für die SQL-Server-Dialog zwischen UserID (1 und 2) nicht gleich wie Unterhaltung zwischen UserID (2 und 1), SQL-Server sehe es als eine andere Dinge.

Also mein Rat wäre, eine andere Tabelle mit dem Namen etwas wie

create table Conversation (ConvoID int, FromID int, ToID int) 

insert into COnversation (ConvoID, FromID, ToID) 
values (1, 1, 2), 
     (1, 2, 1), 
     (2, 1, 3), 
     (2, 3, 1) 

erstellen und dann können Sie Conversation Tabelle auf „Chat“ Tisch sitzen, und gehen mit einer Gruppe von ConvoID und max Datum ... weil dass nur so Chat zwischen zwei Benutzern zu machen, einzigartig sein

0

Versuchen Sie, diese

select c.* from 

(select User1id,User2id,max(time) as newtime 
    from 
    (select 
     case when sent_id < receive_id then sent_id else receive_id 
    end as User1id, 
     case when sent_id > receive_id then sent_id else receive_id 
    end as User2id, 
    time 
    from chats where (Sent_ID = 1 or Receive_ID = 1) 
    ) temp 
    group by User1id,User2id 
)t1 
    inner join chats c on 
    t1.newtime = c.time