nullif函数在两参数相等时返回null,否则返回第一个参数;若任一参数为null则比较结果为unknown,直接返回第一个参数。

NULLIF 函数的基本行为和触发条件
NULLIF 不是条件判断函数,而是“相等则转空”专用函数:它只接收两个参数,当第一个参数与第二个参数完全相等(类型也需兼容,否则可能隐式转换失败或报错),就返回 NULL;否则返回第一个参数的值。它不处理 NULL 本身——如果任一参数为 NULL,比较结果为未知(UNKNOWN),整个表达式直接返回第一个参数(即不变成 NULL)。
常见误用场景:想用 NULLIF(col1, col2) 把两列值相同时设为空,但其中一列含 NULL,结果发现没生效。这是因为 col1 = col2 在任一为 NULL 时恒为假,NULLIF 不触发。
- 正确前提:确保两列都非
NULL,或先用COALESCE/IS NULL预处理 - 字符串比较注意尾部空格:某些数据库(如 SQL Server)默认忽略末尾空格,
'a ' = 'a'为真 →NULLIF('a ', 'a')返回NULL - 数值与字符串混用要小心:如
NULLIF(1, '1')在 PostgreSQL 中报错,在 MySQL 中可能隐式转成数字后相等 → 返回NULL
替代 COALESCE + CASE 的简洁写法
当需要“若 A 等于 B,则取 C,否则取 A”,很多人写 CASE WHEN A = B THEN C ELSE A END。其实可嵌套 NULLIF 实现更短逻辑:COALESCE(NULLIF(A, B), C)。
原理:若 A = B,NULLIF(A, B) 返回 NULL,COALESCE 继而取 C;否则 NULLIF 返回 A,COALESCE 直接返回它。
- 适用场景:报表中“优先显示用户自定义值,若与系统默认值相同则显示‘未覆盖’”
- 注意
COALESCE参数类型需一致,否则可能报错或意外截断 - 性能上与
CASE差异极小,但可读性取决于团队习惯
配合除法避免除零错误的实际用例
最典型的实战用途是保护分母:比如计算转化率时,clicks / impressions,但 impressions 可能为 0。直接写 clicks / NULLIF(impressions, 0) 会返回 NULL 而非报错——因为除以 NULL 结果为 NULL,不会中断查询。
但这只是“不报错”,不是“安全结果”。你需要确认业务是否接受 NULL 表示“不可算”,还是应返回 0 或其他占位值。
- 不要写
clicks / NULLIF(impressions, 0)后直接AVG()——AVG会跳过NULL,导致分母缩小 - 若需统一返回 0,应写
COALESCE(clicks * 1.0 / NULLIF(impressions, 0), 0)(显式转浮点防整除截断) - PostgreSQL 支持
NULLIF(impressions, 0) AS den再在SELECT中复用,MySQL 8.0+ 也可用 CTE 提前计算
NULLIF 在不同数据库中的行为差异
核心逻辑一致,但边界情况处理不同:
- PostgreSQL:严格类型检查,
NULLIF(1, '1')报错;NULLIF(NULL, NULL)返回NULL(因NULL = NULL为假,不触发) - MySQL:允许数值/字符串隐式转换,
NULLIF(1, '1')返回NULL;NULLIF(NULL, 0)返回NULL(第一个参数是NULL,直接返回) - SQL Server:
NULLIF两参数必须同类型或可隐式转换,否则报错;空字符串''和NULL不等价,NULLIF(col, '')不会影响NULL值
跨库迁移时,别只看语法对不对,重点验证含 NULL、空字符串、混合类型的测试数据是否产出预期结果。











