直接在GROUP BY后使用COUNT(DISTINCT column)即可统计每组内该字段的非重复值个数,主流SQL引擎(MySQL 5.7+、PostgreSQL等)均支持;注意不可写成DISTINCT COUNT(),NULL默认被忽略,多列去重需写为COUNT(DISTINCT a,b)表示组合去重。

GROUP BY 后怎么用 COUNT(DISTINCT ...) 正确统计去重数量
直接在 COUNT(DISTINCT ...) 里写字段,再配合 GROUP BY,就能对每组内该字段的不重复值计数。这是标准 SQL 支持的语法,MySQL 5.7+、PostgreSQL、SQL Server、Oracle、SQLite 都可用,但注意早期 MySQL(5.6 及更早)在某些嵌套场景下可能报错。
常见错误是把 DISTINCT 错放在 COUNT 外面,比如写成 DISTINCT COUNT(...) —— 这语法非法,数据库会直接报 ERROR: syntax error at or near "DISTINCT"。
-
COUNT(DISTINCT user_id):统计每组中不同用户数 -
COUNT(DISTINCT CONCAT(city, '-', region)):组合字段去重计数(适用于需要多列联合去重) - 如果字段可能为
NULL,COUNT(DISTINCT ...)会自动忽略NULL,无需额外过滤
遇到 COUNT(DISTINCT) 结果为 0 或比预期少怎么办
不是语法错了,大概率是数据本身或分组逻辑有问题。最常踩的坑是:分组字段和去重字段存在隐式类型转换或空格/大小写干扰。
例如在 MySQL 中,VARCHAR 字段默认比较忽略末尾空格,导致 'A ' 和 'A' 被当成相同值去重;又或者 PostgreSQL 对大小写敏感,而你没意识到 'Email@A.com' 和 'email@a.com' 算两个不同值。
- 先查一组原始数据:
SELECT group_col, target_col FROM t WHERE group_col = 'X' LIMIT 10,人工确认去重依据是否合理 - 需要忽略大小写时,显式转换:
COUNT(DISTINCT LOWER(email)) - 需要去除首尾空格:
COUNT(DISTINCT TRIM(name)) - 确认目标字段没有意外的
NULL占比过高(可用SUM(CASE WHEN col IS NULL THEN 1 ELSE 0 END)辅助检查)
大数据量下 COUNT(DISTINCT) 很慢,有没有替代方案
是的,尤其在 Hive、Spark SQL 或旧版 MySQL 中,COUNT(DISTINCT) 常触发全局去重 shuffle,性能下降明显。这时可考虑近似统计或预处理。
PostgreSQL 可用 APPROX_COUNT_DISTINCT()(基于 HyperLogLog),误差率约 1%;BigQuery 默认就用近似版本;而 MySQL 8.0+ 没有原生近似函数,但可通过 GROUP BY ... WITH ROLLUP + 临时表分步聚合缓解压力。
- 真正要精确结果且数据超千万行:先
CREATE TEMPORARY TABLE uniq AS SELECT DISTINCT group_col, target_col FROM t,再SELECT group_col, COUNT(*) FROM uniq GROUP BY group_col - Hive/Spark 中优先用
approx_count_distinct(col),快一个数量级 - 避免在
COUNT(DISTINCT)里用复杂表达式(如子查询、UDF),会强制物化中间结果
GROUP BY 多个字段时,COUNT(DISTINCT) 的作用域是哪一层
它只对当前 SELECT 中的 GROUP BY 分组生效,不是对全表。换句话说:按 A, B 分组后,COUNT(DISTINCT C) 就是在每个 (A,B) 组合内部统计 C 的不重复值个数。
容易混淆的是,有人误以为加了多个 GROUP BY 字段会让去重范围变“更大”,其实刚好相反——分组越细,每组数据越少,COUNT(DISTINCT) 的结果通常越小(除非某组内 C 全部相同)。
- 语句:
SELECT dept, year, COUNT(DISTINCT emp_id) FROM sales GROUP BY dept, year - 结果中每一行代表“某部门某年”的独立员工数,不是“某部门所有年份”的去重总数
- 若想跨年汇总,得另起查询,或用窗口函数:
COUNT(DISTINCT emp_id) OVER (PARTITION BY dept)(需数据库支持)

















