如何正确使用MySQL DISTINCT实现按token字段去重查询
MySQL按单字段token去重的实现方法
原有语句失效的原因
DISTINCT关键字的去重规则是对SELECT后紧跟的所有字段的组合值进行判定,只有整行所有选中字段的值全部相同时才会被判定为重复。你现有两个token为4567的行text字段值不同,因此会被识别为不同的行,不会被去重。
正确实现方案
场景1:仅需要获取所有不重复的token值,不需要其他关联字段
直接查询token字段加DISTINCT即可:
SELECT DISTINCT token FROM `chatMessages`;
场景2:需要获取每个token对应的完整行数据(MySQL 8.0+版本,推荐)
使用ROW_NUMBER()窗口函数实现,可自定义每个token下保留哪一行:
WITH ranked_msg AS ( SELECT id, token, name, email, text, status, -- 按token分组,相同token的行按id升序排序取序号,要保留最新行就把ASC改成DESC ROW_NUMBER() OVER (PARTITION BY token ORDER BY id ASC) AS rn FROM `chatMessages` ) SELECT id, token, name, email, text, status FROM ranked_msg WHERE rn = 1;
场景3:需要获取每个token对应的完整行数据(MySQL 5.x版本)
使用子查询先筛选每个token对应的目标行id,再关联原表取全量字段:
SELECT c.id, c.token, c.name, c.email, c.text, c.status FROM `chatMessages` c INNER JOIN ( -- 取每个token下id最小的行,要保留最新行就把MIN改为MAX SELECT MIN(id) AS target_id, token FROM `chatMessages` GROUP BY token ) t ON c.id = t.target_id;
注意事项
- 不要直接使用
SELECT * FROMchatMessagesGROUP BY token的写法,开启ONLY_FULL_GROUP_BY规则的MySQL环境会直接报错,且返回的非分组字段值不确定,稳定性极差。 - 可根据业务需求调整排序规则,比如要保留每个token最新的聊天记录,就把排序逻辑改成按id降序即可。
内容的提问来源于stack exchange,提问作者God of all wars
相关产品推荐
相关产品推荐

