【问题标题】:Get last row PER Group获取每组的最后一行
【发布时间】:2011-03-27 01:03:09
【问题描述】:

如何为以下任务制定查询:

假设您以 user:1 身份登录 我想在我进行过的每个对话中获得一排。 对于我想获得的每一行, 对话中第一行的“主题” 第一行的“日期时间” “消息”此对话的最后一条消息,无论是谁写的

创建表消息(
    ID INT NOT NULL AUTO_INCREMENT 主键,
    FromID INT NOT NULL,
    ToID INT NOT NULL,
    对话ID INT NOT NULL,
    主题 varchar(255),
    消息 varchar(255),
    日期时间日期时间
    ) 引擎=InnoDB;


CREATE TABLE 对话(
    ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY
    ) 引擎=InnoDB;



插入对话(ID)值(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");
插入消息(FromID、ToID、ConversationID、主题、消息、日期时间)值(1,2、1、“”、“嘿,你还没有回答”、“2010-08-08 16:23:52”);
插入消息(FromID、ToID、ConversationID、主题、消息、日期时间)值(2,1、1、“”、“嗨,这是我的答案”、“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");
插入消息(FromID、ToID、ConversationID、主题、消息、日期时间)值(1,2、2、“”、“2.Hi back”、“2010-08-08 16:25:52”);
插入消息(FromID、ToID、ConversationID、主题、消息、日期时间)值(2,1、2、“”、“2.Hi 这是我的答案”、“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");
插入消息(FromID、ToID、ConversationID、主题、消息、日期时间)值(1,2、3、“”、“2.Hi back”、“2010-08-08 16:27:52”);
插入消息(FromID、ToID、ConversationID、主题、消息、日期时间)值(1,2、3、“”、“2.你在吗?”、“2010-08-08 16:27:59”) ;

【问题讨论】:

  • 是否只能在 2 个人之间进行对话?即,会话中所有消息的用户 ID 是 FromID 还是 ToID
  • 是的,只有两个人的对话

标签: sql mysql greatest-n-per-group


【解决方案1】:

看看@ROW_NUMBER() in MySQL - 你肯定能把它应用到你的问题上。

【讨论】:

    【解决方案2】:
    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
    

    【讨论】:

    • 嗨马丁,这很好!只是几件事,我收到的消息不是对话中的最新消息,而我真正要查找的 DateTime 是另一个用户在此对话中发送的最后一条消息的时间。
    • 我认为问题可能是您的测试表中的NOW() 意味着所有日期时间都相同?如果是这样,可以使用 id 代替。
    • 没错就是这样!这几乎是完美的,我用新数据编辑了帖子。最后一件事,我怎样才能获得与我对话的用户的 ID 也为每一行(对话)
    • 我认为我的编辑应该适用于明确的规范,但显然可以根据一些数据对其进行测试!
    • 哇 :) 不会想到这一点,非常感谢,很抱歉添加我现在才意识到的一些内容,但我是否也可以获得与每个返回行进行对话的用户的 ID?
    【解决方案3】:

    你应该试试这样的:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-29
      • 2014-11-10
      • 2019-05-24
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多