COALESCE用于兜底NULL,但禁止在WHERE中滥用导致索引失效;NULLIF用于条件转NULL防除零或清洗重复值;二者嵌套需注意NULL传播与类型兼容性,跨库迁移应显式CAST。
COALESCE 用来兜底 NULL,但别在 WHERE 里滥用
的核心作用是按顺序取第一个非
值,常用于字段默认值兜底。比如查用户昵称,优先用
,没有就 fallback 到
:
常见错误是把它塞进
条件里做“模糊匹配”:
❌
—— 这会强制全表扫描,索引失效
✅ 改成:
,再单独处理
分支
注意:所有参数类型必须兼容,否则 PostgreSQL 会报
;MySQL 和 SQL Server 会隐式转换,但行为不可靠。
NULLIF 防止除零或重复值,本质是“条件性转 NULL”
等价于 “如果
,返回
,否则返回
”。最典型场景是避免除零:
另一个实用场景是清洗重复的占位符值:
比如把空字符串、
、
统一转为
,再用
统一兜底:
⚠️ 注意:比较是严格相等(包括类型),
在 PostgreSQL 中不成立(字符串 vs 整数),不会返回
;MySQL 可能隐式转,但别依赖。
COALESCE 和 NULLIF 嵌套时,执行顺序和 NULL 传播要盯紧
嵌套本身合法,但容易误判结果。例如:
结果是:
、
、
—— 因为
返回
(
为
,不触发替换)。
关键点:
•
对
输入直接返回
,不比较
•
遇到
就继续往后找,直到非
或耗尽
• 所有中间表达式都可能产生
,尤其涉及函数调用(如
、
)后接
不同数据库对 NULLIF/COALESCE 的 NULL 处理逻辑一致,但类型推导有差异
标准 SQL 规定两者都遵循“first non-null type”规则,但实际中:
• PostgreSQL 严格按参数列表顺序推导类型,
报错
• MySQL 宽松些,会尝试转成
或
,但结果可能意外截断或精度丢失
• SQL Server 允许混合类型,但以左侧参数类型为准,右侧强制转换 ——
返回
跨库迁移时,别假设类型自动对齐;显式
最稳妥,比如:
NULL 处理看着简单,但嵌套 + 类型 + 索引影响三者叠加,最容易在上线后才发现慢查询或数据偏差。特别是
被用在索引字段上时,那一行的执行计划得亲手
一遍。
COALESCENULLnike_nameuser_idSELECT COALESCE(nike_name, CAST(user_id AS TEXT)) AS display_name FROM users;WHEREWHERE COALESCE(phone, '') LIKE '%123%'WHERE phone IS NOT NULL AND phone LIKE '%123%'NULLERROR: COALESCE types text and integer cannot be matchedNULLIF(a, b)a = bNULLaSELECT amount / NULLIF(quantity, 0) AS unit_price FROM orders;'N/A''unknown'NULLCOALESCECOALESCE(NULLIF(trim(status), ''), 'active')NULLIF('1', 1)NULLSELECT COALESCE(NULLIF(x, 0), 999) FROM (VALUES (0), (1), (NULL)) t(x);9991999NULLIF(NULL, 0)NULLNULL = 0UNKNOWNNULLIFNULLNULLCOALESCENULLNULLNULLtrim()upper()NULLIFCOALESCE('a', 1)DOUBLEVARCHARCOALESCE(GETDATE(), '2020-01-01')DATETIMECASTCOALESCE(CAST(price AS NUMERIC), 0.0)COALESCEEXPLAIN