group by会将所有null值自动归为同一组,既可暴露空值问题(如500条null邮箱),也可能因空字符串、不可见字符或大小写差异导致误分组,需结合trim、lower、正则清洗后验证。

查空值和异常NULL分组
GROUP BY 本身会把所有 NULL 值归为同一组,这在数据质量核对中既是线索也是陷阱。比如你对 email 字段做 GROUP BY email HAVING COUNT(*) > 1,结果里突然冒出一行 NULL 对应的计数为 500,说明有 500 条记录没填邮箱——但这未必是脏数据,得结合业务判断是否允许为空。
更常见的是误判:你以为字段“有值”,其实存的是空字符串 '' 或纯空格 ' ',它们不会被归进 NULL 组,而是各自成组或混入其他值中。所以核对前建议先清洗:
-
WHERE email IS NOT NULL AND TRIM(email) != ''过滤掉无效值再分组 - 若要单独检查空值分布,用
GROUP BY CASE WHEN email IS NULL THEN 'NULL' WHEN TRIM(email) = '' THEN 'EMPTY' ELSE 'VALID' END - MySQL 8.0+ 可配合
COUNT(*) OVER (PARTITION BY email)看每行所属组的基数,不丢失原始记录
识别重复主键或业务键
真正影响数据质量的重复,不是“看起来像”,而是违反唯一性约束的组合。比如订单表中 (user_id, order_date) 理应唯一,但实际出现多条,就属于异常。
直接用 GROUP BY user_id, order_date HAVING COUNT(*) > 1 最快定位。注意三点:
- 多列组合必须全部写进
GROUP BY,漏一个就会让 MySQL(开启ONLY_FULL_GROUP_BY时)报错Expression #1 of SELECT list is not in GROUP BY clause - 如果其中一列含
NULL,例如order_date IS NULL,那所有该情况都会被合并——这不是 bug,是 SQL 标准行为 - 想看到所有重复的原始行?别只依赖
GROUP BY输出汇总,要用子查询或窗口函数,例如:SELECT * FROM orders WHERE (user_id, order_date) IN ( SELECT user_id, order_date FROM orders GROUP BY user_id, order_date HAVING COUNT(*) > 1 );
验证聚合逻辑是否被隐式截断
当你发现 AVG(grade) 结果明显偏低,或 COUNT(*) 总数对不上,可能不是数据问题,而是分组键本身存在隐形不一致。
典型诱因包括:
- 字段含不可见字符(如换行符、零宽空格),
TRIM()不处理,需用REGEXP_REPLACE(col, '[[:cntrl:]]', '')清洗 - 大小写混用导致本该同组的被拆开,例如
'iOS'和'ios',临时方案加GROUP BY LOWER(os_name) - 编码混乱,比如 UTF8mb4 和 latin1 混存,造成相同文字字节不同——这时
GROUP BY分出来的“组”根本不可信,得先统一字符集 - MySQL 关闭
ONLY_FULL_GROUP_BY后,SELECT name, COUNT(*) FROM user GROUP BY dept_id会随机挑一个name返回,若该name恰好是乱码字段,你就误以为数据坏了
用 HAVING 快速卡阈值做异常拦截
数据质量核对不是只看“有没有”,更要判断“多不多”。HAVING 是唯一能在分组后直接加业务规则的地方。
例如检查用户注册渠道质量:
- 单个渠道注册数低于 10?
HAVING COUNT(*) - 某渠道新用户次日留存率低于 5%?先算分组内留存:
AVG(CASE WHEN next_day_active = 1 THEN 1.0 ELSE 0.0 END) - 某地区订单平均金额超过全局均值 3 倍?用子查询先算全局均值,再在
HAVING中引用:HAVING AVG(amount) > (SELECT AVG(amount) FROM orders)
注意:HAVING 不能用别名(如 HAVING avg_amt > 100 会报错),必须写完整表达式;且所有条件都作用于分组后结果,无法访问单行细节——需要明细就得回到窗口函数或关联原表。
真正容易被忽略的,是分组键本身的可信度。你拿 GROUP BY 当放大镜看数据,但如果镜片(即分组字段)本身模糊、变形或带污渍,再精细的观察也只会强化错误认知。每次执行前,先问一句:这个字段的值,真的能代表我要区分的逻辑单元吗?











