nullif(divisor, 0)是避免除零错误的最简方案,它在分母为0时返回null,使除法结果为null而非报错;必须置于分母位置,再配合coalesce或case处理null语义。

NULLIF 怎么用才能避免除零错误
直接说结论:NULLIF 本身不处理除零,但它能配合 COALESCE 或条件逻辑把除数变成 NULL,让整个除法结果为 NULL 而非报错。关键不是“防止除零”,而是“让除零不发生”——靠提前把分母干掉。
为什么 NULLIF(divisor, 0) 是最简解法
NULLIF 的行为是:当两个参数相等时返回 NULL,否则返回第一个参数。所以 NULLIF(x, 0) 在 x = 0 时返回 NULL,其他情况返回 x。这正好把危险的 0 替换成安全的 NULL。
-
SELECT numerator / NULLIF(denominator, 0)—— 如果denominator是 0,整条表达式结果就是NULL,不会报错 - 数据库(PostgreSQL、SQL Server、Oracle、SQLite)都支持该用法;MySQL 也支持,但要注意其
sql_mode若含STRICT_TRANS_TABLES,仍可能报错(见下一条) - 别写成
NULLIF(0, denominator)——顺序反了,那就永远返回 0 或NULL,起不到保护作用
遇到 MySQL 报错 “Division by zero” 怎么办
MySQL 默认在某些模式下对除零更敏感,NULLIF 单独用可能不够。必须确认当前会话的 sql_mode:
- 运行
SELECT @@sql_mode,如果结果含STRICT_TRANS_TABLES或STRICT_ALL_TABLES,就需要额外兜底 - 稳妥写法是套一层
COALESCE或用CASE:COALESCE(numerator / NULLIF(denominator, 0), 0)(把NULL换成 0) - 或者更明确:
CASE WHEN denominator = 0 THEN NULL ELSE numerator / denominator END - 临时禁用严格模式不推荐,影响范围大且不可控
NULLIF 不是万能的,这些地方容易踩坑
NULLIF 只解决“值等于 0”的情况,对 NULL 分母无效——NULLIF(NULL, 0) 返回 NULL,再做除法仍是 NULL,虽不报错但语义模糊。真正健壮的写法要覆盖所有边界:
- 分母可能是
NULL、0、负数、极小浮点数(如1e-15),仅判 0 不够 - 如果业务上“接近零”也要规避,得用
ABS(denominator) 配合 <code>CASE -
NULLIF返回NULL后,后续聚合(如SUM、AVG)会自动忽略它,这点要和业务预期对齐 - 别在
WHERE子句里依赖NULLIF(..., 0) = 0——因为NULL = 0永远是UNKNOWN,条件不成立
真正麻烦的从来不是写一行 NULLIF,而是想清楚:这个除法在业务里到底该返回什么——NULL?0?默认值?还是该由上游拦住?











