COALESCE在PostgreSQL中要求参数类型兼容,MySQL则宽松支持隐式转换;IFNULL仅MySQL可用;ISNULL是SQL Server替换函数,返回类型固定;空字符串等非NULL值需显式清洗。

COALESCE 在 PostgreSQL 和 MySQL 中的行为差异
COALESCE 是标准 SQL 函数,返回参数列表中第一个非 NULL 的值,但不同数据库对类型隐式转换的容忍度不同。PostgreSQL 要求所有参数类型兼容(或能被统一 cast),而 MySQL 更宽松——比如 COALESCE('abc', 123) 在 MySQL 中返回字符串 'abc',在 PostgreSQL 中会报错 ERROR: COALESCE types text and integer cannot be matched。
实操建议:
- 跨数据库迁移时,优先显式转换类型:
COALESCE(col::text, 'default')(PostgreSQL)或COALESCE(CAST(col AS CHAR), 'default')(MySQL) - 避免混合数值与字符串参数,尤其在视图或函数定义中,否则可能在执行计划阶段就失败
- 注意空字符串
''不等于NULL,COALESCE(col, 'N/A')对空字符串无效
IFNULL 只在 MySQL 里可用,别在其他库硬套
IFNULL 是 MySQL 专属函数,仅接受两个参数:IFNULL(expr1, expr2)。它在 SQLite、PostgreSQL 或 SQL Server 中直接报错 Unknown function IFNULL。有人误以为它是通用别名,结果在迁移或 ORM 动态拼 SQL 时踩坑。
实操建议:
- 写 MySQL 专用脚本时可放心用,但若需兼容性,一律改用
COALESCE -
IFNULL对NULL和0的判断是严格区分的,不会把0当作“假值”处理(这点和 PHP 的??不同) - 嵌套使用易读性差:
IFNULL(IFNULL(a, b), c)不如COALESCE(a, b, c)直观且可变长
ISNULL 在 SQL Server 中有两个完全不同的重载版本
SQL Server 的 ISNULL 不是布尔判断函数,而是替换函数,签名是 ISNULL(check_expression, replacement_value)。但它和 COALESCE 关键区别在于:返回类型始终和 check_expression 一致,不按参数中最高精度推导。例如 ISNULL(CAST(1 AS TINYINT), 1000) 会截断为 255(溢出),而 COALESCE(CAST(1 AS TINYINT), 1000) 返回 1000(类型升为 INT)。
实操建议:
- 若字段是
DECIMAL(5,2),用ISNULL(col, 0.00)安全;但用ISNULL(col, 999.999)会四舍五入或报错,取决于版本 - 不要用
ISNULL替代EXISTS或WHERE col IS NULL,它的语义是“替换”,不是“判断” - 在计算列或索引表达式中,
ISNULL比COALESCE更可能被优化器内联,性能略优,但可读性代价高
NULL 处理中最容易被忽略的边界:空字符串、零长度、JSON null
数据库里 NULL 是缺失值,但业务中常混入空字符串 ''、全空格字符串、0(如金额)、甚至 JSON 字段里的 null 值(字符串 "null")。这些都不会被 COALESCE / IFNULL / ISNULL 捕获。
实操建议:
- 清洗数据时先统一空值语义:
NULLIF(TRIM(col), '')把空白转为NULL,再套COALESCE - 对 JSON 字段,SQL Server 用
JSON_VALUE(col, '$.field')返回NULL表示路径不存在或值为 JSONnull;MySQL 8.0+ 的JSON_EXTRACT同理,但需配合->>操作符才能自动展开为标量 - 应用层传参时,明确约定前端不传
""表示“清空”,而应传NULL,否则 SQL 层永远要多一层CASE WHEN col = '' THEN NULL ELSE col END










