使用 distinct 或 group by 可实现 mysql 去重,distinct 适用于简单去重,group by 支持聚合统计,结合窗口函数可保留最新记录,建议建立索引以提升性能。

在MySQL中进行去重查询,主要是为了消除查询结果中的重复记录,只保留唯一的数据行。最常用的方式是使用 DISTINCT 关键字,也可以结合 GROUP BY 实现更灵活的去重操作。
使用 DISTINCT 去重
DISTINCT 用于返回唯一不同的值,语法简单,适合基础去重场景。
基本语法:SELECT DISTINCT 列名 FROM 表名;
假设有一张用户订单表 orders,其中 user_id 存在重复,想要查询所有下单过的用户ID:
SELECT DISTINCT user_id FROM orders;
这条语句会返回所有不重复的 user_id。
如果需要对多个字段联合去重,比如查出唯一的用户姓名和城市组合:
SELECT DISTINCT name, city FROM users;
此时只有当 name 和 city 都相同时,才会被视为重复并被去除。
使用 GROUP BY 实现去重
GROUP BY 通常用于分组统计,但也能实现去重效果,尤其适合需要配合聚合函数(如 COUNT、MAX 等)的场景。
基本语法:SELECT 列名 FROM 表名 GROUP BY 列名;
同样查询不重复的 user_id:
SELECT user_id FROM orders GROUP BY user_id;
结果与使用 DISTINCT 相同。但如果还想统计每个用户有多少订单,可以这样写:
SELECT user_id, COUNT(*) as order_count FROM orders GROUP BY user_id;
这在去重的同时还提供了额外信息,是 DISTINCT 无法直接实现的。
去重并保留某条记录(如最新的一条)
有时去重不只是拿唯一值,而是希望在重复数据中保留一条有意义的记录,比如按时间保留最新的那条。
常见做法是结合子查询或窗口函数(MySQL 8.0+ 支持)。例如,在用户登录日志表 login_log 中,每个用户每天可能有多次记录,现在要查出每个用户最近一次的登录记录:
使用窗口函数 ROW_NUMBER():
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_time DESC) as rn FROM login_log) t WHERE rn = 1;
这里按 user_id 分组,按登录时间倒序排序,给每条记录编号,只取编号为1的记录,即最新登录。
注意事项
DISTINCT 作用于整行数据,多个字段时会对组合值去重。
GROUP BY 要求 SELECT 中的非聚合字段必须出现在 GROUP BY 子句中(MySQL 某些模式下宽松,但建议遵守)。
去重会影响查询性能,尤其是大数据量表,建议在相关字段上建立索引。
如果只是统计去重后的数量,可以直接用:SELECT COUNT(DISTINCT user_id) FROM orders;
基本上就这些。根据实际需求选择 DISTINCT 或 GROUP BY,复杂场景可配合子查询或窗口函数处理。不复杂但容易忽略细节。










