空字符串 '' 和 NULL 默认不合并,因SQL标准规定NULL不等于任何值(含自身),而''是合法非空字符串,语义、类型、比较结果均不同;主流数据库均将其分属不同组。

不能直接让空字符串 '' 和 NULL 在 GROUP BY 中自动视为同一组 —— 它们默认就是不同组,必须显式转换。
为什么空字符串和 NULL 默认不合并?
SQL 标准规定:NULL 不等于任何值(包括自己),而 '' 是一个合法的非空字符串值,二者语义、类型、比较结果都不同。所有主流数据库(MySQL、PostgreSQL、SQL Server)在 GROUP BY col 时都会把 NULL 归为一组、'' 归为另一组,互不影响。
- 执行
SELECT col, COUNT(*) FROM t GROUP BY col后,你大概率会看到两行:一行col = NULL,一行col = '' - 哪怕业务上你认为“没填”和“填了空格/空串”都算“无效”,数据库也不会替你做这个判断
- 依赖 collation 或隐式转换去“碰运气”合并,极不可靠,且跨库不兼容
用 COALESCE 或 CASE 统一映射成相同占位值
最稳妥的做法是,在 GROUP BY 和 SELECT 中**同步使用同一个表达式**,把 NULL 和 '' 都转成同一个语义化值(比如 'unknown')。
- MySQL 推荐:
COALESCE(NULLIF(col, ''), 'unknown')—— 先用NULLIF(col, '')把''变成NULL,再用COALESCE把所有NULL(含原生和转化来的)统一为'unknown' - 通用写法(全数据库兼容):
CASE WHEN col IS NULL OR col = '' THEN 'unknown' ELSE col END - 务必确保
SELECT列和GROUP BY子句中用的是**完全相同的表达式**,否则报错或逻辑错乱 - 别只改
SELECT而漏掉GROUP BY,这是新手最高频错误
注意类型一致性与排序副作用
把字符串和 NULL 强制转成统一值后,可能引发隐式类型转换,影响排序和索引使用。
- 如果原字段是
INT,别用COALESCE(col, 'unknown')—— 字符串会触发全表转字符排序,性能暴跌;应选COALESCE(col, -1)等同类型默认值 -
ORDER BY时,'unknown'会按字典序排在最前(ASCII 小),若想排最后,得加ORDER BY (CASE ... END) = 'unknown' ASC, ...这类技巧 - 该转换表达式无法走索引,分组量大时建议提前物化(如建生成列或汇总表)
真正难的不是写对那一行 CASE,而是确认业务上「空字符串」和「NULL」是否真的该归为一类——有时候它们代表完全不同的含义(比如 NULL 是未采集,'' 是采集到但为空),强行合并反而掩盖问题。

















