DISTINCT 是 MySQL 中最常用、最直接的去重方式,作用于 SELECT 列的整体组合,只保留唯一行;它不能指定保留哪一条、不支持大字段高效去重,且无法替代 GROUP BY 或窗口函数实现分组取最新 / 最高记录等需求。

MySQL 中的 DISTINCT 是最常用、最直接的去重方式,它作用于查询结果的整行(即所有 SELECT 列的组合),只保留唯一的一组值。
DISTINCT 基础用法:单列去重
当你只想查看某列有哪些不重复的值时,直接在 SELECT 后加 DISTINCT 即可:
- SELECT DISTINCT status FROM orders; —— 获取订单表中所有不同的状态值(如 ‘pending’, ‘shipped’, ‘cancelled’)
- 注意:DISTINCT 必须紧跟在 SELECT 后面,不能写成 SELECT status DISTINCT。
DISTINCT 多列组合去重
当需要基于多个字段判断“是否重复”时,DISTINCT 会对这些列的 ** 整体组合 ** 去重:
- SELECT DISTINCT user_id, product_id FROM purchases; —— 返回每个用户购买过的不同商品组合,同一用户买同一件商品多次,只算一条
- 如果某两行在所有指定列上完全相同,就视为重复,只保留其中一行
注意 DISTINCT 的局限性和常见误区
DISTINCT 不是万能去重 工具,使用时需留意以下几点:
- 它只作用于 SELECT 子句中的字段,不影响 WHERE 或 ORDER BY;想按某字段排序再取唯一值,需配合 ORDER BY(但不能保证取的是“第一条”,除非结合 LIMIT 和子查询)
- DISTINCT 无法指定“保留哪一条”(比如最新 / 最早那条),它只是任意保留满足条件的一行。如需按时间取最新记录,应改用 GROUP BY + 聚合函数(如 MAX(create_time))或窗口函数(如 ROW_NUMBER())
- 对大字段(如 TEXT、BLOB)或大量数据使用 DISTINCT 可能影响性能,因为 MySQL 需要临时排序或哈希去重
替代方案:什么时候不该用 DISTINCT?
当你的目标不是“查出所有不同组合”,而是“每个分组取一条代表记录”时,DISTINCT 就不合适了:
- 想查每个用户的最新一条订单:用 GROUP BY user_id + MAX(order_time) 或子查询
- 想查每个部门工资最高的员工:用窗口函数 ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC)
- 要去除表中真实存在的重复数据(物理删除):需用 DELETE + JOIN 或临时表,DISTINCT 只用于查询,不修改数据