首页/数据/SQL 速查/COALESCE 取首个非 NULL 值
函数速查60 条

COALESCE 取首个非 NULL 值

按顺序返回首个非 NULL 的参数:做默认值、多字段兜底、把 NULL 转成业务默认值时使用,是 SQL 标准函数。

SQL 速查数据更新于 2026-10-13

COALESCE 是什么

COALESCE 按顺序返回第一个非 NULL 的参数,是处理空值最通用的工具:做默认值、多字段兜底、把 NULL 换成业务默认值都靠它。它是 SQL 标准函数,MySQL、PostgreSQL、SQL Server、Oracle 都支持。与 MySQL 专有的 IFNULL 相比,COALESCE 可以接受任意多个参数;与 PostgreSQL 的 NULLIF 方向正好相反,后者是「相等就返回 NULL」。兜底后结果的数据类型由参数列表中优先级最高的类型决定,混用数字与字符串时要留意。

基本信息

作用按顺序返回首个非 NULL 参数,全部为 NULL 时返回 NULL
参数个数任意多个;MySQL 的 IFNULL 只能写两个
返回类型由参数列表中类型优先级最高的那个决定
平台差异MySQL 另有 IFNULL,PostgreSQL 另有 NULLIF(语义相反)
与 CASE 的关系等价于逐级判断的 CASE WHEN … IS NOT NULL THEN …
适用平台标准 SQL,MySQL 8.0 与 PostgreSQL 均支持

典型使用场景

  • 给可空列设默认值:COALESCE(nickname, name, '匿名')
  • 展示兜底:接口把 NULL 换成空串或占位文案,避免前端处理空值
  • 多字段取第一个有值的:手机号缺失时用备用联系方式
  • 拼接前兜底:COALESCE(CONCAT(a, b), '')
  • 统计兜底:COALESCE(SUM(amount), 0) 让无数据时返回 0
  • 计算兜底:把可能为 NULL 的列先补默认值再参与算术,防止整列变 NULL

示例

示例
SELECT COALESCE(nickname, name, '匿名')     AS display_name,   # 逐级兜底
       COALESCE(phone, backup_phone, '')    AS contact,        # 取第一个有值的
       COALESCE(SUM(o.amount), 0)           AS total          # 无数据时给 0
FROM users AS u
LEFT JOIN orders AS o ON o.user_id = u.id
GROUP BY u.id;

-- 拼接前兜底,避免 MySQL 的 CONCAT 遇 NULL 后整体变 NULL
SELECT CONCAT('name: ', COALESCE(nickname, '')) FROM users;

空值处理函数对照

函数作用平台与注意
COALESCE(a, b, …)返回首个非 NULL 参数标准 SQL,通用
IFNULL(a, b)a 为 NULL 时返回 bMySQL 专有,只能两个参数
NULLIF(a, b)a 与 b 相等时返回 NULL标准 SQL,与兜底方向相反
ISNULL(a)判断是否为 NULLMySQL 返回 0 或 1,SQL Server 语义不同
IF(a, b, c)条件表达式MySQL 专有,PostgreSQL 用 CASE WHEN
COALESCE 的返回类型由参数里优先级最高的类型决定:COALESCE(int_col, '0') 在 PostgreSQL 里会因为类型推断报错,混用类型时显式转换更稳。
对聚合结果兜底是常见写法:SUM、AVG、MIN、MAX 在无匹配行时返回 NULL,直接展示会出现空值,套一层 COALESCE 更符合报表预期。
兜底会掩盖数据缺失:把 NULL 一律换成 0 或空串后,缺失与真实为 0 无法区分,做数据质量统计时要保留原始判断。
判断「两个列是否相同」时用 COALESCE 先统一空值再比较,比 IS DISTINCT FROM 更易读,但在大表上会让列索引失效。

实践要点

  • 参数按优先级排列:最可能为空的放前面,最不容易为空的放最后
  • 兜底值要与业务一致:字符串用空串、数值用 0、金额用 0.00,避免类型混用
  • 拼接与算术前先兜底,能一次性消除整列变 NULL 的问题
  • 接口层兜底与数据库层兜底选一个,两层都写会让默认值来源难以追踪
  • 统计场景优先 COALESCE(SUM(x), 0),而不是在应用层判断空值
  • 跨库迁移时留意 IFNULL、NVL 这类专有函数的替换

常见误用

  • 把 COALESCE 写在 WHERE 的条件列外侧,导致该列索引失效、退化为全表扫描
  • 兜底值选成了业务上有意义的值(如 0),真实值与默认值从此无法区分
  • 忘记聚合函数在无数据时返回 NULL,报表直接显示空白
  • 多层兜底的参数顺序写反,取到了优先级更低的字段值
  • 拼接文本前不做兜底,一行 NULL 就让整列结果变成空
  • 跨库迁移时把 MySQL 的 IFNULL 直接搬过去,目标库不认这个函数
COALESCE 与 CASE 可以互相改写:单纯做空值兜底用 COALESCE 更短,需要先比较再取值这类复杂判断时才用 CASE。
兜底值尽量选业务上不可能出现的占位,例如字符串用空串、数值用 NULL 友好的默认值;把真实值可能取到的数字当兜底,会让两件事无法区分。

易错点

  • 把 COALESCE 的兜底值写成了错误类型,跨库时类型推断报错或发生隐式转换
  • 在 WHERE 里对列套 COALESCE,导致该列索引失效、退化为全表扫描
  • 用兜底值掩盖了数据缺失,报表上 0 与 NULL 混为一谈,口径失真
  • 以为 IFNULL 与 COALESCE 完全等价,迁移到不支持 IFNULL 的数据库时才发现
  • 参数顺序写反,取到了优先级更低的字段值,展示结果与预期不符

数据来源与参考

  • MySQL 8.0 Reference Manual · Comparison Functions
  • PostgreSQL Documentation · Conditional Expressions
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌