获取每组的最后一行
Posted
技术标签:
【中文标题】获取每组的最后一行【英文标题】: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
?
是的,只有两个人的对话
【参考方案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
【讨论】:
以上是关于获取每组的最后一行的主要内容,如果未能解决你的问题,请参考以下文章