DISTINCT 是什么
DISTINCT 对结果集去重,作用于整个 SELECT 列清单,而不是某一列。常见误解是 SELECT DISTINCT a, b 只按 a 去重,实际是按 (a, b) 的组合去重。统计去重个数要用 COUNT(DISTINCT col),它与 COUNT(col) 的结果不同。DISTINCT 通常需要排序或哈希来实现,数据量越大代价越高,能靠索引顺序天然去重的场景应尽量避免额外的 DISTINCT。
基本信息
| 作用 | 对结果集按整行去重 |
|---|---|
| 作用范围 | 整个 SELECT 列清单,不是单列 |
| 去重计数 | COUNT(DISTINCT col),与 COUNT(col) 不同 |
| 实现方式 | 通常需要排序或哈希,代价随结果集增长 |
| 与 GROUP BY | 只做去重时两者等价,需要聚合时必须用 GROUP BY |
| 适用平台 | 标准 SQL,MySQL 8.0 与 PostgreSQL 一致 |
典型使用场景
- 取唯一值列表:城市、类目、标签等枚举值
- 生成下拉选项:后台筛选框的可选值
- 去重计数:COUNT(DISTINCT user_id) 求独立用户数
- 数据体检:去掉重复视角看真实基数,评估索引选择性
- 多列组合去重:检查 (a, b) 组合是否唯一
- 中间结果去重:UNION 两个查询结果时有自动去重效果
示例
示例
SELECT DISTINCT city FROM users; # 单列去重
SELECT DISTINCT city, province FROM users; # 按组合去重,不是只按 city
SELECT COUNT(DISTINCT user_id) FROM orders; # 去重计数
-- 只去重不聚合时,与 GROUP BY 等价
SELECT city FROM users GROUP BY city;
-- 需要同时去重并聚合时用 GROUP BY
SELECT city, COUNT(*) FROM users GROUP BY city;相关写法对照
| 写法 | 含义 | 注意 |
|---|---|---|
| SELECT DISTINCT city | 按 city 去重 | 单列时最直观 |
| SELECT DISTINCT a, b | 按 (a,b) 组合去重 | 不是只按 a 去重 |
| COUNT(DISTINCT col) | 去重计数 | 忽略 NULL |
| GROUP BY a | 分组去重 | 可同时做聚合 |
| UNION | 合并并去重 | UNION ALL 不去重更快 |
DISTINCT 加在 SELECT 后面,作用于所有输出列;只要多输出一列,去重粒度就随之变化,改 SQL 时容易在这里踩坑。
DISTINCT 与 ORDER BY 一起用时会先排序再去重,结果顺序可能变化;需要固定顺序就显式写 ORDER BY。
如果查询原本要按某列去重并取该组的其他字段,DISTINCT 表达不了,改用 GROUP BY 或 ROW_NUMBER 选行。
DISTINCT 与 GROUP BY 在只做去重时等价,选哪个看上下文:要顺带看每组的数量就用 GROUP BY,纯取唯一值用 DISTINCT 更直观。