case when 是 sql 标准的 if-else 语法,所有主流数据库均支持;where 中不可用 if/else,仅能用布尔表达式或搜索 case(支持任意条件);简单 case 仅限等值匹配且无法处理 null,搜索 case 支持范围、空值及多列判断;必须以 end 结尾,各分支类型需兼容,条件顺序影响结果;if() 是 mysql 特有二元函数,可读性差、不跨库、难维护,非必要不替代 case。

CASE WHEN 就是 SQL 里的 if-else,不是“类似”,它就是标准写法,所有主流数据库都认。
WHERE 子句里能不能直接写 IF 或 ELSE?
不能。MySQL、PostgreSQL、SQL Server 等都不允许在普通查询的 WHERE 中使用 IF() 或 ELSE 关键字——那属于存储过程语法,用在 SELECT 外会直接报错 ERROR 1064。
- 想在过滤条件里做分支?直接写布尔表达式,比如
WHERE status = 'active' AND score > 60,比套一层CASE清晰又快 - 真要动态判断(比如按地区启用不同阈值),得把逻辑拆到
SELECT或JOIN后再过滤,而不是硬塞进WHERE里用CASE包裹 -
IF()函数虽可在WHERE中用(如WHERE IF(id > 100, 1, 0) = 1),但可读性差、无法利用索引,属于反模式
CASE WHEN 的两种写法:什么时候用简单 CASE,什么时候必须用搜索 CASE?
简单 CASE 只支持等值匹配,形如 CASE column WHEN 'a' THEN ...;搜索 CASE 支持任意布尔表达式,形如 CASE WHEN x > 0 AND y IS NOT NULL THEN ...。
- 字段值做单值映射(如状态码转中文)可用简单
CASE,但实际中占比不到 5% - 涉及范围判断(
>=、BETWEEN)、空值检查(IS NULL)、多列组合(type = 'vip' AND amount > 1000)时,必须用搜索CASE - 简单
CASE无法处理NULL:当column是NULL时,所有WHEN 'x'都不匹配,直接跳到ELSE;而搜索CASE可显式写WHEN column IS NULL THEN ...
漏写 END、类型不一致、顺序错乱——三个高频翻车点
CASE 表达式必须以 END 结尾,否则解析失败;各 THEN 分支返回值类型需兼容;条件顺序影响结果,且不回溯。
- 漏
END:语句直接报错,例如CASE WHEN x > 0 THEN 'yes'缺少END,MySQL 返回ERROR 1064 - 类型冲突:若一个分支返回字符串
'A',另一个返回数字95,PostgreSQL 会报错,MySQL 可能隐式转成字符串但截断或补零,建议统一用CAST(... AS VARCHAR) - 顺序陷阱:写价格分级时,如果先写
WHEN score 再写 <code>WHEN score >= 90,那所有 95 分的人永远进不了第二分支——因为第一条件已为真,后续不再判断
IF() 函数能不能替代 CASE?什么场景下值得用?
IF() 是 MySQL 特有函数,仅限二选一,语法紧凑但扩展性差;CASE 是标准语法,天然支持多分支和 NULL 显式控制。
-
IF()在简单场景下确实快:比如SELECT IF(is_deleted = 1, '已删', '正常'),比等价的两行CASE少敲几个字 - 但嵌套三层以上就难维护:
IF(a=1, 'x', IF(b=2, 'y', IF(c=3, 'z', 'other'))),不如直接写搜索CASE -
IF()对NULL的处理是“当作 FALSE”,而CASE可独立判断WHEN x IS NULL,更可控 - 跨数据库迁移时,
IF()必须重写;CASE几乎不用改
真正容易被忽略的是:CASE 表达式本身不慢,但人容易把它当“万能胶”往里塞子查询、函数调用——比如每个 THEN 里都写 (SELECT COUNT(*) FROM log WHERE user_id = t.id),这会让执行计划崩掉。该提前 JOIN 的数据,别指望 CASE 帮你实时算。










