SQL COALESCE 和 NULLIF 怎么用?
面试怎么回答
COALESCE 返回第一个非 NULL 值,适合多来源取值和缺失兜底;NULLIF 在两值相等时返回 NULL,常用于把空字符串、哨兵值标准化,或保护除零分母。二者组合时我会写成 COALESCE(NULLIF(TRIM(col), ''), fallback),既保留真实值,也处理空串。但兜底不等于修复源数据,核心字段还要监控缺失率,并区分“无法计算”和真实的 0。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
一列渠道名称里同时出现 NULL、空字符串和 unknown;另一个指标计算转化率时,分母又可能是 0。
很多人会顺手加一个 COALESCE,但跑完才发现:空字符串还在,除零错误也没解决。
这两个函数经常一起出现,但职责不同:COALESCE 从左到右返回第一个非 NULL 值;NULLIF 在两个表达式相等时返回 NULL,否则返回第一个表达式。
COALESCE 不是“第一个有效值”
COALESCE(channel_name, '未知')
它只能兜底 NULL。空字符串 ''、数字 0、字符串 'null' 都不是 SQL NULL,不会被替换。
如果空字符串也应视为缺失,可以先标准化:
COALESCE(NULLIF(TRIM(channel_name), ''), '未知')
处理顺序是:先去掉首尾空格;如果结果为空字符串,NULLIF 把它变成 NULL;最后 COALESCE 返回“未知”。

NULLIF 最常见的用途是保护分母
pay_user_cnt * 1.0 / NULLIF(visit_user_cnt, 0)
当访问人数是 0 时,NULLIF(visit_user_cnt, 0) 返回 NULL,从而避免除零报错,结果通常为 NULL。
如果报表明确要求无分母时展示 0,可以再套一层:
COALESCE(
pay_user_cnt * 1.0 / NULLIF(visit_user_cnt, 0),
0
) AS conversion_rate
但这里要警惕:“无法计算”与“转化率确实为 0”不是同一个业务含义。 是否把 NULL 展示为 0,要由指标口径决定,不能为了页面好看直接填充。
兜底值不能覆盖真实值
生产改 SQL 时,一个常见错误是直接把字段写成固定值:
'default_id' AS material_id
这会把已有真实值也覆盖掉。真正的兜底应保留有效数据:
COALESCE(NULLIF(material_id, ''), 'default_id') AS material_id
如果 0 也是业务合法值,就不能把 NULLIF(material_id, 0) 当清洗模板。哨兵值必须依据字段定义确定。
还要注意类型一致
COALESCE 的候选表达式需要能归并到兼容类型。数值列用字符串 '未知' 兜底,可能报错或触发隐式转换。日期、数值、字符串应该分别使用同类型默认值,必要时显式 CAST。
另外,COALESCE 只能改善结果展示或下游兼容性,不能证明源数据已经完整。大量默认值可能把上游缺失悄悄隐藏。核心字段应同时保留缺失率监控,必要时增加 is_fallback 标识。
怎么选择?
- 多个来源按优先级取值:COALESCE
- 把某个特定哨兵值转为 NULL:NULLIF
- 空字符串清洗后再兜底:NULLIF + COALESCE
- 避免除零:分母使用 NULLIF
- 无法计算是否再变成 0:由指标定义决定