我的消息表格式如下:
btack.cpp
我想要做的就是获得所有"对话"已登录用户(例如ID为2的用户)以及该对话的最后消息。 我设法提取用户id2的用户使用此查询的消息:
+------------------------------------------------------------------+
| id|sender_id| recipient_id | message_text |created_at |
+------------------------------------------------------------------+
| 1 | 2 | 10 | "test1" |"2017-04-10 09:05:45" |
| 2 | 10 | 2 | "test2" |"2017-04-10 09:05:47" |
| 3 | 2 | 4 | "test3" |"2017-04-10 09:05:49" |
| 4 | 10 | 4 | "test4" |"2017-04-10 09:05:51" |
| 5 | 4 | 2 | "test5" |"2017-04-10 09:05:53" |
| 6 | 2 | 10 | "test6" |"2017-04-10 09:05:58" |
+------------------------------------------------------------------+
这会产生什么
select distinct users.id
from messages, users where
(recipient_id = 2 and users.id = sender_id)
or
(sender_id = 2 and users.id = recipient_id);
因为user2已发送和/或接收来自这两个人的消息(4
10
为test1, test2, test6
,10
为test3, test5
。
我无法做的是修改此查询,以便它还会生成发送到已生成ID的最后一条消息 - 例如
4
答案 0 :(得分:3)
如果我正确理解您的要求,您希望获取涉及特定用户的每个对话的最新消息日期。在这种情况下,我们可以聚合给定用户的会话并保留最近的消息日期。
SELECT m1.*
FROM messages m1
INNER JOIN
(
SELECT LEAST(sender_id, recipient_id) AS first,
GREATEST(sender_id, recipient_id) AS second,
MAX(created_at) AS recent_date
FROM messages
WHERE sender_id = 2 OR recipient_id = 2
GROUP BY LEAST(sender_id, recipient_id),
GREATEST(sender_id, recipient_id)
) m2
ON LEAST(m1.sender_id, m1.recipient_id) = m2.first AND
GREATEST(m1.sender_id, m1.recipient_id) = m2.second AND
m1.created_at = m2.recent_date
<强>输出:强>
<强>解释强>
此查询中的挑战是找到一种方法将两个用户之间的对话分组在一起。我使用LEAST/GREATEST
技巧,这是一种我们可以将2 -> 4
和4 -> 2
对话视为逻辑相同的方式。然后,使用GROUP BY
,我们可以确定该对转化用户的最近通话日期。因此,上面我的答案中的子查询发现,对于每对用户,不考虑任何顺序,该对以及最近的对话日期。然后,我们将此结果返回到messages
表,以引入实际的最新消息文本。
在这里演示:
答案 1 :(得分:0)
在查询结尾处使用order_by created_at desc
语句来获取最新消息。