按时间排序查找表中唯一对话对,获取用户间最后对话的查询方法
这个问题很常见,核心是要统一对话对的标识——不管消息是A发给B还是B发给A,都要把它们归到同一个对话组里。下面给你两种实用的SQL实现方案,适配大多数主流数据库(比如MySQL、PostgreSQL、SQL Server):
方法一:用窗口函数(推荐,简洁直观)
通过LEAST()和GREATEST()函数生成唯一的对话组键(把两个用户ID按“小值在前、大值在后”的规则组合),再用窗口函数给每个组内的消息按时间倒序排号,取排号为1的那条就是最新对话。
WITH ranked_messages AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY LEAST(senderId, receiverId), GREATEST(senderId, receiverId) ORDER BY created_at DESC ) AS rn FROM messages ) SELECT senderId, receiverId, content, created_at FROM ranked_messages WHERE rn = 1;
方法二:分组关联法(适合不支持窗口函数的旧版数据库)
先按对话组分组,找出每个组的最新消息时间,再关联原表拿到对应完整消息:
SELECT m.* FROM messages m JOIN ( SELECT LEAST(senderId, receiverId) AS user_a, GREATEST(senderId, receiverId) AS user_b, MAX(created_at) AS latest_time FROM messages GROUP BY user_a, user_b ) latest ON LEAST(m.senderId, m.receiverId) = latest.user_a AND GREATEST(m.senderId, m.receiverId) = latest.user_b AND m.created_at = latest.latest_time;
额外优化提示
如果你的消息表有自增的唯一ID(比如messageId),建议用MAX(messageId)替代MAX(created_at)来判断最新消息——因为可能存在同一时间多条消息的情况,自增ID能更精准定位到最新的那一条。
内容的提问来源于stack exchange,提问作者helloJSON
相关产品推荐
相关产品推荐

