COALESCE 是 SELECT 投影阶段从左到右取首个非 NULL 值的函数,参数顺序决定结果,需确保类型兼容、显式消歧、正确处理空字符串和隐式转换。

COALESCE 不是用来“处理多列默认值”的配置工具,它是在 SELECT 投影阶段对已查出的列值做一次从左到右的 NULL 扫描——只要顺序写对、类型兼容、显式消歧,就能稳定拿到你想要的兜底结果。
COALESCE 参数顺序决定实际返回值
它不关心字段来源是主表还是 LEFT JOIN 表,只按你写的参数顺序取第一个非 NULL 值。顺序错了,就永远拿不到预期 fallback。
- 正确写法:
COALESCE(t2.email, t1.backup_email, '未提供')—— 优先用关联表邮箱,没有再用主表备用邮箱,最后兜底字符串 - 错误写法:
COALESCE(t1.backup_email, t2.email, '未提供')—— 即使t2.email有值,t1.backup_email非 NULL 就直接返回,后面全跳过 - LEFT JOIN 后
t2.email为NULL是常态,但如果你把t1.backup_email放左边,等于主动绕过真实数据
所有参数必须能隐式转成同一类型
MySQL 会尝试统一类型,但转换规则常导致意外结果:时间字段混进字符串,可能变成 '0000-00-00' 或科学计数法;数字混进空字符串,可能转成 0。
- 安全组合:
COALESCE(t2.updated_at, t1.created_at)(同为DATETIME) - 危险组合:
COALESCE(t2.updated_at, 'never')→ 触发隐式转换,报错Illegal mix of collations或返回不可读字符串 - 若真要混合类型,先用
CAST或DATE_FORMAT统一格式,例如:COALESCE(DATE_FORMAT(t2.updated_at, '%Y-%m-%d'), 'N/A')
别名冲突和空字符串陷阱
COALESCE 只判 NULL,不判空字符串 '' 或零值 0。另外,多表同名字段不加前缀,会因作用域模糊直接报错。
- 两表都有
status字段?必须写成COALESCE(t1.status, t2.status, 'pending'),不能只写status - 字段允许空字符串但业务上等价于缺失?得先用
NULLIF(col, '')转换:COALESCE(NULLIF(t2.phone, ''), NULLIF(t1.mobile, ''), '暂无') -
COALESCE(SUM(amount), 0)必须加——聚合无匹配时返回NULL,不是0,这点极易被忽略
真正卡住人的从来不是语法,而是类型隐式转换边界和空字符串语义差异。写完 COALESCE,务必用真实 NULL / '' / 0 数据组合跑一遍测试,别只看文档里的理想示例。


















