如何通过MySQL查询获取聊天消息表的唯一详情?
获取与用户相关的最新聊天消息详情
我明白你想要的是和用户6相关的每一组聊天对话里的最新一条消息详情——也就是每个聊天对象(不管是你发消息给对方,还是对方发给你)的最后那条记录。下面是完整的实现方案:
1. 先明确表结构
先把enrich_chat_message的字段含义列出来,方便理解逻辑:
| 字段名 | 说明 |
|---|---|
id | 消息唯一ID(一般是自增主键) |
sent_by | 发件人用户ID |
message | 消息内容 |
read | 是否已读标记(0=未读,1=已读) |
received_by | 收件人用户ID |
created_at | 消息发送时间 |
updated_at | 消息更新时间(比如标记已读时更新) |
2. 完整查询方案
要实现你的需求,核心是先把双向聊天归为同一组(比如用户6和1的聊天,不管谁发谁收,都算同一组),然后取出每组的最新消息,再关联回原表获取完整详情。
基础版SQL(假设ID自增,最新消息ID最大)
SELECT m.* FROM enrich_chat_message m INNER JOIN ( -- 子查询:分组获取每个对话的最新消息ID SELECT -- 用LEAST和GREATEST固定用户ID顺序,确保双向聊天被归为同一组 LEAST(sent_by, received_by) AS user_a, GREATEST(sent_by, received_by) AS user_b, MAX(id) AS latest_msg_id FROM enrich_chat_message -- 筛选所有和用户6相关的消息 WHERE sent_by = 6 OR received_by = 6 GROUP BY user_a, user_b ) latest ON m.id = latest.latest_msg_id -- 按消息时间倒序,最新的聊天排在最前面 ORDER BY m.created_at DESC;
逻辑拆解
LEAST(sent_by, received_by)和GREATEST(sent_by, received_by):这两个函数会把对话双方的ID按大小排序,比如sent_by=6, received_by=1和sent_by=1, received_by=6都会被分到user_a=1, user_b=6这一组,避免同一对话被拆成两组。MAX(id):假设你的id是自增主键,那么最新的消息ID肯定最大;如果你的业务里消息ID和发送时间不一定严格同步,可以换成MAX(created_at)。- 最后关联原表,就能拿到该最新消息的所有详情了。
进阶版SQL(用窗口函数,更灵活)
如果你的业务场景中,可能存在同一时间多条消息、或者ID和发送时间不同步的情况,用窗口函数会更可靠:
SELECT * FROM ( SELECT *, -- 给每组对话的消息按发送时间倒序编号,最新的消息编号为1 ROW_NUMBER() OVER ( PARTITION BY LEAST(sent_by, received_by), GREATEST(sent_by, received_by) ORDER BY created_at DESC, id DESC ) AS rn FROM enrich_chat_message WHERE sent_by = 6 OR received_by = 6 ) temp -- 只取每组的第一条(最新)消息 WHERE rn = 1 ORDER BY created_at DESC;
这个方案会给每个对话组的消息按时间倒序排号,取编号为1的就是最新消息,比基础版更灵活。
3. 针对你的示例数据的执行结果
用你提供的三条示例数据,执行上述查询后会得到:
| id | sent_by | message | read | received_by | created_at | updated_at |
|---|---|---|---|---|---|---|
| 786 | 6 | Hi | 0 | 1 | 2018-04-26 13:00:15 | 2018-04-26 13:00:15 |
| 774 | 211 | Hello | 1 | 6 | 2018-04-26 12:20:25 | 2018-04-26 12:59:59 |
这就是用户6和每个聊天对象的最新一条消息详情啦。
内容的提问来源于stack exchange,提问作者user3201500
相关产品推荐
相关产品推荐

