CodeGym /课程 /SQL SELF /条件表达式: CASE <表达式> WHEN ... THEN ... ELSE ......

条件表达式: CASE <表达式> WHEN ... THEN ... ELSE ... END

SQL SELF
第 10 级, 课程 1
可用

如果你已经了解 CASE,那你知道它可以直接把逻辑写进查询里。但其实 CASE 有两种写法。如果你用 CASE WHEN ...,那就是类似 if-else 的条件判断,而简单 CASE 更像其他语言里的 switch-case:它会把一个表达式和多个值比较,然后执行对应的分支。

当你要把某个字段和固定值比较时,这种写法更简洁直观。

简单 CASE 的语法

CASE expression
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ...
    ELSE default_result
END

很简单:

  • expression —— 要和 value1、value2 等值比较的表达式或字段。
  • THEN 表示如果匹配就返回什么。
  • ELSE —— 如果都不匹配就返回什么(可以省略,但最好别省)。

例子:学生成绩

假设有个 students 表,里面有个 grade 字段,存的是 2 到 5 的整数。我们想把分数转成文字显示。

SELECT
    name,
    grade,
    CASE grade
        WHEN 5 THEN '优秀'
        WHEN 4 THEN '良好'
        WHEN 3 THEN '及格'
        WHEN 2 THEN '不及格'
        ELSE '未知'
    END AS 文字成绩
FROM students;

这里 CASE 会把 grade 字段的值和 2、3、4、5 这些固定值比较。

例子:商品类别代码

在 products 表里有个 category_code 字段,存的是像 'el'、'frn'、'bks' 这样的短标签。我们想显示可读的类别名称。

SELECT
    product_name,
    category_code,
    CASE category_code
        WHEN 'el' THEN '电子产品'
        WHEN 'frn' THEN '家具'
        WHEN 'bks' THEN '图书'
        ELSE '其他'
    END AS category_name
FROM products;

这种写法特别适合把“代码”转成“人话”来显示。

例子:月份名称

有时候我们想根据数字显示月份的中文名:

SELECT
    EXTRACT(MONTH FROM order_date) AS month_number,
    CASE EXTRACT(MONTH FROM order_date)
        WHEN 1 THEN '一月'
        WHEN 2 THEN '二月'
        WHEN 3 THEN '三月'
        WHEN 4 THEN '四月'
        WHEN 5 THEN '五月'
        WHEN 6 THEN '六月'
        WHEN 7 THEN '七月'
        WHEN 8 THEN '八月'
        WHEN 9 THEN '九月'
        WHEN 10 THEN '十月'
        WHEN 11 THEN '十一月'
        WHEN 12 THEN '十二月'
        ELSE '未知'
    END AS month_name
FROM orders;

这样用简单 CASE,数字 1 到 12 就能一目了然地变成中文月份。

简单 CASE 里处理 NULL

要注意,如果你和 NULL 比较,结果会是 NULL,因为 NULL = NULL —— 不是 true,而是未知。

NULL 的例子:

SELECT
    user_id,
    status,
    CASE status
        WHEN 'active' THEN '活跃'
        WHEN 'blocked' THEN '已封禁'
        WHEN NULL THEN '无状态'  -- 不会生效!
        ELSE '未知'
    END AS 用户状态
FROM users;

别用 WHEN NULL,要用 ELSE,或者直接用搜索型 CASE(我们上节课讲过):

CASE
    WHEN status IS NULL THEN '无状态'
    ...

和搜索型 CASE 的对比

特点 简单 CASE 搜索型 CASE
和具体值比较 ✅ 很方便 ❌ 不适合
条件灵活性(>, IS NULL) ❌ 不行 ✅ 可以
编程里的类比 switch-case if-else

实用场景

例子:申请状态可视化

request_id status
101 new
102 in_progress
103 done
104 cancelled
105 NULL
SELECT
    request_id,
    CASE status
        WHEN 'new' THEN '🟡 新建'
        WHEN 'in_progress' THEN '🔵 处理中'
        WHEN 'done' THEN '🟢 已完成'
        ELSE '⚪ 未知'
    END AS 状态标签
FROM requests;
request_id 状态标签
101 🟡 新建
102 🔵 处理中
103 🟢 已完成
104 ⚪ 未知
105 ⚪ 未知

这里 CASE 就像翻译器,把技术状态变成易懂(还挺可爱)的标签。如果状态未知或 NULL —— 用户会看到 ⚪「未知」。

例子:报表里的分类分组

employee_id name department
1 Alex Lin HR
2 Maria Chi IT
3 Anna Song IT
4 Otto Art FIN
5 Jane Doe HR
6 Max Gray SALES
7 Zoe Black IT
8 Tom Brown FIN
9 Liam Park NULL
10 Eva Gold HR
SELECT
    CASE department
        WHEN 'HR' THEN '人事'
        WHEN 'IT' THEN '技术'
        WHEN 'FIN' THEN '财务'
        ELSE '其他'
    END AS 部门名称,
    COUNT(*) AS 员工数
FROM employees
GROUP BY
    CASE department
        WHEN 'HR' THEN '人事'
        WHEN 'IT' THEN '技术'
        WHEN 'FIN' THEN '财务'
        ELSE '其他'
    END;

结果:

部门名称 员工数
人事 3
技术 3
财务 2
其他 2

这里发生了什么:

  • HR 部门的员工归到“人事”类别。
  • IT 就是“技术”。
  • FIN 就是“财务”。
  • 其他的,包括 SALES 和 NULL,都归到“其他”。这种方式很适合做友好易懂的报表。

常见错误

  • 忘了写 ELSE → 如果都不匹配就会得到 NULL。
  • 和 NULL 比较 → 不生效,要用 IS NULL 和搜索型 CASE。
  • 类型不兼容 → 比如 CASE grade WHEN '5',但 grade 是数字类型。

简单 CASE —— 当你要把一个值和一堆可能的值比较时,就是你的好帮手。它简洁、易读,特别适合文本分类、可视化、代码转文本、分组等场景。

如果你要判断区间、NULL 或更复杂的条件 —— 用搜索型 CASE。SQL 喜欢清晰。CASE 就是你让逻辑变清晰的利器。

2
任务
SQL SELF, 第 10 级, 课程 1
已锁定
为成绩分配文本描述
为成绩分配文本描述
2
任务
SQL SELF, 第 10 级, 课程 1
已锁定
商品类别对照
商品类别对照
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION