条件取值函数的可移植性
MySQL 有一个条件取值函数,按条件在三个参数里挑一个返回,写法接近编程语言里的三元表达式,能直接出现在查询列表、条件表达式甚至排序里,还可以嵌套。PostgreSQL 在表达式层面没有对应函数,只能写成标准的条件分支表达式,条件语句本身只存在于存储过程代码中。跨库项目里最省事的做法是统一用标准分支表达式,它在两种数据库上都能跑,也不必为迁移再改一遍。
基本信息
| 适用平台 | MySQL 8.0 / PostgreSQL 12 及以上 |
|---|---|
| MySQL 写法 | 条件取值函数,三个参数依次是判断条件、成立取值、不成立取值 |
| PostgreSQL 写法 | 表达式位置只能用标准分支表达式,函数只存在于过程语言中 |
| 通用写法 | 标准分支表达式,两库语法一致 |
| 空值兜底 | MySQL 有专用空值替换函数,PostgreSQL 用通用的合并函数 |
典型使用场景
- 状态打标:库存大于零显示有货,否则显示缺货
- 金额分档:按阈值把金额归入不同区间,便于分组统计
- 空值兜底:城市字段为空时统一显示未知,避免前端出现空白
- 排序权重:把某个状态的数据排到前面,用于运营后台的待办列表
- 报表可读化:把数字状态码换成中文文字,导出时直接可用
两库写法对照
两库写法对照
-- MySQL:条件取值函数可嵌套,也可与空值函数组合
SELECT IF(qty > 0, 'in_stock', 'sold_out') AS state FROM products;
SELECT IFNULL(NULLIF(city, ''), '未知') FROM users; -- 先去空再兜底
SELECT IF(amount >= 1000, 'A', IF(amount >= 100, 'B', 'C')) AS grade FROM orders;
-- PostgreSQL:表达式位置用标准分支表达式
SELECT CASE WHEN qty > 0 THEN 'in_stock' ELSE 'sold_out' END AS state
FROM products;
SELECT COALESCE(NULLIF(city, ''), '未知') FROM users;
SELECT CASE WHEN amount >= 1000 THEN 'A'
WHEN amount >= 100 THEN 'B'
ELSE 'C' END AS grade FROM orders;
-- 两库通用:分支表达式写在排序里做优先级排序
-- ORDER BY CASE WHEN status = 'pending' THEN 0 ELSE 1 END, created_at同一需求的两种写法
| 需求 | MySQL | PostgreSQL |
|---|---|---|
| 条件取值 | 条件取值函数,三个参数 | 标准分支表达式 |
| 空值替换 | 专用空值替换函数 | 通用合并函数 |
| 空字符串兜底 | 先用比较函数把空串转成空值再兜底 | 先用比较函数再合并 |
| 多分支分档 | 函数嵌套,层数越多越难读 | 分支表达式逐行排列,可读性好 |
条件取值函数嵌套三层以上可读性会急剧下降,评审时经常看错分支。分档逻辑建议直接用分支表达式,或者先在子查询里算出一个派生标记列,外层再用于分组。
空字符串与空值是两回事:从外部导入的数据里常见空字符串,直接做兜底不会命中,需要先把空字符串转成空值再替换,两个函数配合使用。