COALESCE参数严格从左到右扫描,首个非NULL值即返回;必须类型兼容,空字符串需用NULLIF转换,GROUP BY中使用需同步处理。

COALESCE参数顺序决定fallback优先级
它不按“重要性”自动排序,只严格从左到右扫描——第一个非NULL值立刻返回,后面全被跳过。写错顺序等于主动丢弃真实数据。
-
COALESCE(t2.email, t1.backup_email, '未提供'):正确。优先用关联表邮箱,没匹配再 fallback 主表备用邮箱 -
COALESCE(t1.backup_email, t2.email, '未提供'):错误。哪怕t2.email有值,只要t1.backup_email非NULL,就永远拿不到关联数据 - LEFT JOIN 后
t2.email为NULL是常态,但 fallback 逻辑是否生效,完全取决于你在COALESCE里写的先后位置
所有参数必须类型兼容,否则隐式转换会出事
MySQL 会尝试把所有参数转成同一类型,但规则不可控:字符串混时间可能变'0000-00-00',数字混空串可能转成0,结果既难读又难 debug。
- 安全组合:
COALESCE(t2.updated_at, t1.created_at)(同为DATETIME) - 危险组合:
COALESCE(t2.updated_at, 'never')→ 触发隐式转换,大概率报Illegal mix of collations - 真要混合类型,先显式转换:
COALESCE(DATE_FORMAT(t2.updated_at, '%Y-%m-%d'), 'N/A')
COALESCE只认NULL,不认空字符串或零值
业务上''和NULL常等价,但COALESCE完全无视前者。直接写COALESCE(phone, mobile),哪怕phone = ''也会原样返回,不会继续看mobile。
- 字段允许空字符串但语义缺失?得先用
NULLIF清洗:COALESCE(NULLIF(t2.phone, ''), NULLIF(t1.mobile, ''), '暂无') - 多表同名字段(如两表都有
status)必须加前缀:COALESCE(t1.status, t2.status, 'pending'),否则报错或结果错乱 - 聚合函数返回
NULL时也得包一层:COALESCE(SUM(amount), 0),不加的话整组无数据就真返回NULL
别在GROUP BY里裸用COALESCE处理分组键NULL
如果category列本身含NULL,想把它归为'Uncategorized',不能只在SELECT里写COALESCE(category, 'Uncategorized')就完事。
- 必须同步出现在
GROUP BY子句:GROUP BY COALESCE(category, 'Uncategorized') - 某些旧版 MySQL 不支持函数直接进
GROUP BY,得改用列别名或 CTE 预处理 - 更稳妥做法:用子查询先统一处理字段,避免
SELECT和GROUP BY里重复写COALESCE表达式
COALESCE后最容易翻车的地方。别只拿NULL测试,一定要用NULL、''、0、datetime混合组合跑一遍真实数据。

















