2010-08-08 6 views
1

Comment puis-je formuler une requête pour la tâche ci-dessous:Obtenez la dernière ligne par groupe

Disons que vous êtes connecté en tant qu'utilisateur: 1 Je veux obtenir une ligne par des conversations que j'ai eu. Pour chaque ligne que je veux, le « Objet » de la première ligne dans la conversation « DateTime » de la première ligne « Message » dernier message de cette conversation, peu importe qui l'a écrit

CREATE TABLE messages (
    ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    FromID INT NOT NULL, 
    ToID INT NOT NULL,  
    ConversationID INT NOT NULL,  
    Subject varchar(255), 
    Message varchar(255), 
    DateTime DATETIME          
    ) ENGINE=InnoDB; 


CREATE TABLE conversations (
    ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY          
    ) ENGINE=InnoDB; 



INSERT INTO conversations (ID) VALUES (1), (2), (3); 
INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (1,2, 1, "Hi", "This is a test message", "2010-08-08 16:23:48");   
INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (1,2, 1, "", "Hey again you have not answered", "2010-08-08 16:23:52");                                    
INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (2,1, 1, "", "Hi this is my answer", "2010-08-08 16:23:59"); 


INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (2,1, 2, "2.Hi", "2.This is a test message", "2010-08-08 16:25:48");   
INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (1,2, 2, "", "2.Hi back", "2010-08-08 16:25:52");                                    
INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (2,1, 2, "", "2.Hi this is my answer", "2010-08-08 16:25:59"); 


INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (2,1, 3, "3.Hi", "3.This is a test message", "2010-08-08 16:27:48");   
INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (1,2, 3, "", "2.Hi back", "2010-08-08 16:27:52"); 
INSERT INTO messages (FromID, ToID, ConversationID, Subject, Message, DateTime) VALUES (1,2, 3, "", "2.Hello are you there?", "2010-08-08 16:27:59");                                    

+0

sont des conversations seulement entre 2 personnes? c'est-à-dire que l'ID utilisateur sera soit le "FromID" soit le "ToID" pour tous les messages d'une conversation? –

+0

Oui la conversation est seulement entre deux personnes – user391986

Répondre

1
SELECT M.ConversationID, 
MAX(CASE WHEN M.DateTime = X.FirstRow THEN M.Subject END) AS Subject, 
CAST(COALESCE(MAX(CASE WHEN M.DateTime = X.LastRowSentByOtherUser 
         THEN M.DateTime END),X.LastRow) AS DateTime)AS LastTime, 
MAX(CASE WHEN M.DateTime = X.LastRow THEN M.Message END) AS Message, 
MAX(CASE WHEN FromID = 1 THEN ToID ELSE FromID END) AS OtherParticipantId 
FROM messages M 
JOIN (
    SELECT ConversationID, MIN(DateTime) AS FirstRow, MAX(DateTime) AS LastRow, 
    MAX(CASE WHEN FromID<>1 THEN DateTime END) AS LastRowSentByOtherUser 
    FROM messages 
    WHERE FromID=1 OR ToID=1 
    GROUP BY ConversationID 
) X ON X.ConversationID = M.ConversationID 
AND (M.DateTime IN (X.FirstRow, X.LastRow, X.LastRowSentByOtherUser)) 
GROUP BY M.ConversationID 
HAVING MAX(CASE WHEN M.DateTime = X.LastRowSentByOtherUser 
        THEN M.DateTime END) IS NOT NULL 
+0

Salut Martin c'est gentil !! Juste des choses, le message que je reçois n'est pas le dernier de la conversation et le DateTime que je cherche réellement est l'heure du dernier message envoyé par l'autre utilisateur dans cette conversation. – user391986

+0

Je pense que le problème pourrait être le 'NOW()' dans votre table de test signifiant que tous les datettimes sont les mêmes? Si c'est le cas, l'identifiant pourrait être utilisé à la place. –

+0

Yap c'était ça! C'est presque parfait, j'ai édité le post avec de nouvelles données. Dernière chose comment puis-je aussi obtenir l'ID de l'utilisateur qui a une conversation avec moi aussi pour chaque rangée (conversation) – user391986

1

Jetez un oeil @ROW_NUMBER() in MySQL - vous serez en mesure d'appliquer cela à votre problème à coup sûr.

1

Vous devriez essayer quelque chose comme ceci:

SELECT 
    m1.Subject, 
    m1.DateTime, 
    m2.Message 
FROM conversations c 
INNER JOIN 
    (SELECT MIN(ID) AS minID, 
      MAX(ID) AS maxID, 
      ConversationID 
    FROM messages 
    WHERE FromID = @userID OR ToID = @userID 
    GROUP BY ConversationID) AS cGrouped 
ON c.ConversationID = cGrouped.ConversationID 
INNER JOIN messages m1 ON m1.ID = cGrouped.minID 
INNER JOIN messages m2 ON m2.ID = cGrouped.maxID