SQL中如何使用GROUP BY合并双向会话的消息统计结果
解决方案
方案1:合并双向会话统计总消息数
核心思路是通过LEAST()和GREATEST()函数对每条消息的两个用户ID做归一化处理,保证同一对用户的分组键始终一致,不受收发方向影响,大部分主流SQL数据库(MySQL、PostgreSQL、SQLite等)都支持这两个函数。
示例SQL:
SELECT LEAST(from_user, to_user) AS from_user, GREATEST(from_user, to_user) AS to_user, COUNT(*) AS nb_messages FROM `messages` GROUP BY LEAST(from_user, to_user), GREATEST(from_user, to_user)
执行后即可得到合并双向会话后的总消息数结果,分组规则固定将ID更小的用户放在from_user列,ID更大的放在to_user列。
方案2:分别统计收发数量
基于用户ID归一化的思路,使用条件聚合分别统计不同方向的消息数即可实现你要的细分统计效果:
SELECT LEAST(from_user, to_user) AS from_user, GREATEST(from_user, to_user) AS to_user, SUM(CASE WHEN from_user = LEAST(from_user, to_user) THEN 1 ELSE 0 END) AS nb_messages_sent, SUM(CASE WHEN from_user = GREATEST(from_user, to_user) THEN 1 ELSE 0 END) AS nb_messages_received FROM `messages` GROUP BY LEAST(from_user, to_user), GREATEST(from_user, to_user)
输出结果中nb_messages_sent为小ID用户发给大ID用户的消息数,nb_messages_received为大ID用户发给小ID用户的消息数,和你要求的输出格式完全匹配。
兼容性说明
如果使用的数据库不支持LEAST/GREATEST函数,可以用CASE语句替换实现相同的排序逻辑:
-- 等价于LEAST(from_user, to_user) CASE WHEN from_user < to_user THEN from_user ELSE to_user END -- 等价于GREATEST(from_user, to_user) CASE WHEN from_user > to_user THEN from_user ELSE to_user END
内容的提问来源于stack exchange,提问作者TitoDev
相关产品推荐
相关产品推荐

