MySQL实现uID列去重并返回全列的SELECT查询需求
MySQL 按uID去重并返回全字段的实现方案
针对你给出的yourTable表结构(自增主键为ID,uID存在重复值,需要按uID去重并返回对应行的所有列),直接提供可落地的可执行写法,分场景适配不同MySQL版本和业务需求:
方案1:兼容所有MySQL版本(含5.x),每个uID保留指定时间的记录
表中ID为自增主键,同一个uID下ID值越小代表数据插入越早,ID值越大代表插入越新。通过分组拿到每个uID对应的目标ID,再回表关联查询全字段,完全适配MySQL默认的严格SQL模式,不会触发ONLY_FULL_GROUP_BY语法报错。
- 保留每个uID最早插入的记录:
SELECT t.* FROM yourTable t INNER JOIN ( -- 按uID分组,拿到每个uID对应的最小主键ID SELECT uID, MIN(ID) AS target_id FROM yourTable GROUP BY uID ) dedup ON t.ID = dedup.target_id;
- 如果需要保留每个uID最新插入的记录,只需要把子查询里的
MIN(ID)替换成MAX(ID)即可。
方案2:MySQL 8.0及以上版本适用,灵活自定义去重保留规则
通过窗口函数实现,不需要嵌套关联查询,可灵活调整重复行的保留逻辑,适合对去重规则有自定义要求的场景:
SELECT * FROM ( SELECT t.*, -- 按uID分区,自定义排序规则给重复行编号 ROW_NUMBER() OVER ( PARTITION BY uID ORDER BY ID ASC -- 此处可自定义排序逻辑,比如换成ORDER BY studyID DESC,就保留每个uID下studyID最大的行 ) AS row_rank FROM yourTable t ) ranked WHERE row_rank = 1;
避坑提醒:不要直接写
SELECT * FROM yourTable GROUP BY uID这类偷懒写法
MySQL 5.7及以上版本默认开启ONLY_FULL_GROUP_BY严格模式,这类写法会直接抛出语法错误;就算手动关闭严格模式,MySQL也会随机返回每个uID对应的任意一行字段值,结果不可控,完全不适合生产场景使用。
如果表数据量超过百万级,可以给uID列加上普通索引,能大幅降低上述查询的耗时。
内容的提问来源于stack exchange,提问作者user2016210
相关产品推荐
相关产品推荐

