nullif能拦住除零错误,因为它在除数等于0时返回null,使被除数除以null得null而非报错;必须写成nullif(除数, 0)置于除法表达式分母位置,不可倒置或包裹整个除法。

NULLIF 为什么能拦住除零错误
因为 NULLIF(a, b) 在 a 和 b 相等时返回 NULL,否则返回 a。把它用在除数位置,只要除数可能为零,就用 NULLIF(除数, 0) 替代——当除数真是 0 时,整个表达式变成 被除数 / NULL,结果就是 NULL,而不是报错。
实际写法:把除数包进 NULLIF 就行
别去判断、别加 CASE、也别提前 WHERE 过滤。直接在除法表达式里替换除数:
SELECT amount / NULLIF(quantity, 0) AS unit_price FROM sales;
常见误写包括:
- 写成
NULLIF(amount / quantity, 0)—— 错,除法已经执行了,早崩了 - 写成
NULLIF(quantity, 0) = 0再分支 —— 多此一举,NULLIF本意就是“替换成空” - 用
COALESCE(NULLIF(quantity, 0), 1)强行补 1 —— 改变了业务语义,不是防错,是造假
和 CASE WHEN 对比:什么时候该换用 NULLIF
NULLIF 适合「只要除数为零就静默转空」的场景;CASE 更适合需要自定义 fallback 值(比如返回 -1、0 或特定字符串)或叠加多个条件判断的情况。
例如:
- 报表中单位价格允许为空 → 用
NULLIF - 前端要求显示“N/A”字符串 → 得套一层
COALESCE(..., 'N/A')或用CASE - 除数可能为
NULL且你也想让它变空 →NULLIF本身不处理NULL,得先COALESCE(quantity, 0)或直接CASE WHEN quantity IS NULL OR quantity = 0 THEN NULL ELSE ... END
注意 NULL 传播和下游兼容性
NULLIF(x, 0) 返回 NULL 后,整个算术表达式结果也是 NULL。这意味着:
- 聚合函数如
SUM()、AVG()会自动忽略这些NULL行,通常符合预期 - 如果下游应用没处理
NULL(比如某些 ORM 映射字段设为NOT NULL),可能抛异常或截断 - PostgreSQL 和 SQL Server 行为一致;MySQL 5.7+ 也支持,但旧版本需确认
真正容易漏掉的是:当除数字段本身允许 NULL 时,NULLIF(quantity, 0) 不会动它——NULL / NULL 还是 NULL,不会报错,但逻辑上你可能希望把原始 NULL 也归为“无效除数”。这时候就得显式处理。











