聚合函数忽略null而非视作0,coalesce(sum(col), 0)用于空组返回0,sum(coalesce(col, 0))则将null当0参与计算,二者语义不同且不可互换。

聚合函数里 NULL 会直接消失,不是变成 0
这是最常被误判的一点:SUM、AVG、COUNT 这些函数天然忽略 NULL,但不会把它当 0 处理。比如 SUM(col) 遇到 [1, NULL, 3],结果是 4,不是 4(没错,看起来一样),但如果是 [NULL, NULL],结果就是 NULL,不是 0——这在报表或前端展示时容易炸掉。
所以别指望聚合自动兜底,得自己干预。
- 用
COALESCE(SUM(col), 0)把最终聚合结果的NULL换成0 - 如果想让参与计算的每个值都不为
NULL,得在聚合前处理:SUM(COALESCE(col, 0)) - 二者语义不同:
COALESCE(SUM(...), 0)是“空组返回 0”,SUM(COALESCE(..., 0))是“把空值当 0 加进去”
COALESCE 和 IFNULL/ISNULL 的兼容性陷阱
不同数据库对空值兜底的支持函数名不一样,硬写 COALESCE 最稳妥,它是 SQL 标准函数,MySQL、PostgreSQL、SQL Server、Oracle 全支持;而 IFNULL(MySQL)、ISNULL(SQL Server)都是方言,换库就报错。
-
COALESCE接受多个参数,返回第一个非NULL值,比如COALESCE(a, b, 0) -
IFNULL(a, 0)只能两个参数,ISNULL(a, 0)参数顺序还反着(SQL Server 中是ISNULL(表达式, 替代值)) - 在视图或 ORM 的 raw SQL 里,优先写
COALESCE,省得迁移时翻车
GROUP BY 后 COALESCE 放哪?别包错位置
常见错误是把 COALESCE 套在 GROUP BY 字段上,比如 GROUP BY COALESCE(name, '未知')——这确实能合并空名字,但和聚合空值无关。用户真正要的是:分完组后,每组的聚合结果不为 NULL。
- 正确位置是聚合函数外层:
SELECT dept, COALESCE(AVG(salary), 0) FROM emp GROUP BY dept - 如果
salary全是NULL,AVG返回NULL,外层COALESCE才起作用 - 别写成
AVG(COALESCE(salary, 0))——这会让平均值失真(比如原数据是[NULL, 10000],后者算出 5000,前者才是NULL→0)
性能提醒:COALESCE 本身不伤性能,但别滥用在 WHERE 里
COALESCE 是标量函数,用在 SELECT 列里几乎无开销;但一旦写进 WHERE 条件,比如 WHERE COALESCE(status, 'active') = 'active',可能让索引失效——因为数据库没法直接拿索引去匹配函数结果。
- 这种场景更适合用
status = 'active' OR status IS NULL,可走索引 - 聚合 +
COALESCE在SELECT或HAVING里是安全的 - 如果表很大、且经常按“空或某值”过滤,考虑加计算列 + 索引(如 PostgreSQL 的
CREATE INDEX ON t ((COALESCE(status, 'active'))))










