case when是sql标准中唯一被广泛支持的条件分支语法,分简单case(等值判断)和搜索case(任意布尔表达式),95%场景用后者;必须写end,不可独立成句,仅用于表达式上下文,各分支结果类型需一致。

SQL里没有IF-ELSE,但CASE WHEN就是它的等价写法
CASE WHEN 不是“类似”IF-ELSE,它就是 SQL 标准中唯一被广泛支持的条件分支语法。几乎所有主流数据库(MySQL、PostgreSQL、SQL Server、Oracle、SQLite)都支持,且行为基本一致。别试图找 IF() 或 ELSE IF——那些要么是方言(如 MySQL 的 IF() 函数仅限表达式上下文),要么根本不合法。
CASE WHEN 有两种写法:简单 CASE 和搜索 CASE
简单 CASE 只能做等值判断,形如 CASE column WHEN 'a' THEN ... WHEN 'b' THEN ... END;搜索 CASE 更常用,支持任意布尔表达式,语法是 CASE WHEN condition THEN ... WHEN condition THEN ... ELSE ... END。实际业务中 95% 的场景该用搜索 CASE。
常见错误包括:
- 漏写
END—— 会直接报错,比如CASE WHEN x > 0 THEN 'pos'缺少END - 在
WHERE子句里误用完整 CASE 表达式(如WHERE CASE WHEN x > 0 THEN 1 ELSE 0 END = 1),其实直接写x > 0更清晰高效 -
ELSE被省略且无匹配项时返回NULL,可能引发后续计算异常(比如聚合时被忽略)
CASE WHEN 必须用在表达式能出现的位置
它不是控制流语句,不能独立成行或包裹多条 SQL。只能出现在:SELECT 列列表、ORDER BY、HAVING、甚至某些数据库的 GROUP BY 中。不能用于动态切换表名、字段名或跳过某段逻辑。
典型用法示例:
SELECT
name,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 70 THEN 'C'
ELSE 'F'
END AS grade
FROM students;
注意:CASE 表达式的结果类型由各 THEN 分支推导,如果分支返回不同类型(如字符串和数字),数据库会尝试隐式转换——可能出错或截断,建议显式统一,比如都用 CAST(... AS VARCHAR)。
性能与可读性:别在 CASE 里塞复杂子查询
CASE WHEN 本身开销极小,但若每个 THEN 分支里都调用一次 (SELECT COUNT(*) FROM ...),那性能就崩了——因为每行都可能触发多次全表扫描。需要提前把子查询结果 JOIN 进来,再在 CASE 中引用字段。
另一个易忽略点:CASE 表达式里的条件按顺序求值,第一个为真即停止。所以高频条件往前放,避免每次都判断低概率分支。比如用户状态字段中 'active' 占 90%,就该把 WHEN status = 'active' 放第一行。
嵌套 CASE 是允许的,但超过两层就该考虑是否该拆成视图或 CTE,否则维护成本陡增。










