聚合函数默认忽略null而非视作0:sum/avg/max/min跳过null,count(col)仅计非null,整列null时返回null;coalesce(sum(c),0)先聚合后兜底,sum(coalesce(c,0))先补零后聚合;where中慎用coalesce以防索引失效;跨库兼容首选coalesce。

聚合函数真不把 NULL 当 0,别信直觉
这是最常翻车的点:写 SUM(salary) 或 AVG(score) 时,如果某几行是 NULL,它们不是被“当成 0 加进去”,而是直接从计算池里剔除。比如数据是 [100, NULL, 200],SUM 返回 300(不是 300),AVG 返回 150(不是 100)。但如果整列都是 NULL,SUM 和 AVG 都返回 NULL——报表一渲染就报错或空白。
-
COUNT(*)统所有行,含NULL;COUNT(col)只数非NULL值 -
SUM/AVG/MAX/MIN全部跳过NULL,不补 0、不报错、不警告 - 空组(如
GROUP BY dept中某部门全员salary IS NULL)→ 聚合结果就是NULL,不是 0
COALESCE(SUM(col), 0) vs SUM(COALESCE(col, 0)):语义完全不同
这两个写法看着像,但干的事完全相反,换错一个就导致业务逻辑出错。
-
COALESCE(SUM(col), 0):先聚合,再兜底。适用于“空组该显示 0”的场景(如统计每个部门总薪资,没人的部门显示 0) -
SUM(COALESCE(col, 0)):先替换,再聚合。适用于“想把缺失值当 0 算进总数”的场景(如库存汇总,缺记录就当 0 件) - 错误示例:
AVG(COALESCE(salary, 0))会把[NULL, 10000]算成5000,而真实业务中这两人可能根本没发薪,不该拉低平均值
别在 WHERE 里套 COALESCE,索引大概率失效
COALESCE 在 SELECT 列里很轻量,但一旦进 WHERE,数据库通常没法用上索引。
- 危险写法:
WHERE COALESCE(status, 'active') = 'active'→ 全表扫描风险高 - 推荐写法:
WHERE status = 'active' OR status IS NULL→ 条件可下推,能走索引 - 若真要高频查“空或某值”,不如建计算列+索引,例如 PostgreSQL:
CREATE INDEX ON t ((COALESCE(status, 'active')))
跨数据库兼容?只信 COALESCE,别碰 IFNULL/ISNULL
硬写 IFNULL(MySQL)、ISNULL(SQL Server)等于埋迁移雷:换库就报错,ORM 生成的 raw SQL 尤其容易中招。
-
COALESCE(a, b, c, 0)是 SQL 标准,MySQL / PG / Oracle / SQL Server 全支持 -
IFNULL(a, 0)仅 MySQL;ISNULL(a, 0)在 SQL Server 里参数顺序还反着(ISNULL(表达式, 替代值)) - 视图、CTE、存储过程里统一用
COALESCE,省得后期重构时逐个改函数名










