0Pricing
SQL Academy · 课时

CASE 表达式

在查询中使用 IF/THEN 逻辑

CASE 表达式 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。

SQL 中的分支逻辑

有时,您需要让查询做出判断:如果满足这个条件,就执行那个操作,否则执行其他操作。SQL 提供了 CASE 表达式来实现这一点。

CASE 让您可以根据条件返回不同的值,并且可以直接在 SELECT 中使用。可以将其看作 SQL 版本的条件分支链。

SELECT name,
       CASE WHEN price > 100 THEN 'expensive'
            ELSE 'affordable'
       END AS price_band
FROM products;

CASE 的结构

一个 CASE 表达式包含几个部分:

  • WHEN condition THEN value — 一个或多个分支
  • ELSE value — 可选的备用值
  • END — 结束表达式(必须提供!)

SQL 会从上到下计算 WHEN 分支,并返回第一个为真的分支的值。

CASE WHEN condition1 THEN result1
     WHEN condition2 THEN result2
     ELSE default_result
END

CASE 返回一个值

关键概念是:CASE 表达式会为每一行计算出一个值。由于它会生成一个值,因此可以在任何允许使用值的地方使用它 — 在 SELECT 列表、WHERE、ORDER BY 中,甚至在函数内部。

这里,它会为每个订单标注一个简单的状态。

SELECT order_id,
       CASE WHEN shipped_at IS NOT NULL THEN 'shipped'
            WHEN paid_at IS NOT NULL THEN 'paid'
            ELSE 'pending'
       END AS status
FROM orders;

第一个匹配项优先

顺序很重要。SQL 会依次检查每个 WHEN,并在遇到第一个为真的分支时停止。即使后面的分支也能匹配,也会被忽略。

下面,金额超过 1000 的订单是'大额',而不会是'中额',因为第一个匹配的分支优先。

SELECT order_id, total,
       CASE WHEN total >= 1000 THEN 'large'
            WHEN total >= 100  THEN 'medium'
            ELSE 'small'
       END AS size_band
FROM orders;

ELSE 分支

ELSE 分支用于处理所有其他情况。如果没有任何 WHEN 条件为真,CASE 就会返回 ELSE 的值。

如果省略 ELSE 且没有任何匹配项,CASE 会返回 NULL。这经常会导致意外的 NULL 值,因此如果您希望得到明确的备用结果,请添加明确的 ELSE。

SELECT name,
       CASE WHEN stock = 0 THEN 'out of stock' END AS note
FROM products;
-- rows with stock > 0 get NULL in note (no ELSE)

条件可以是任意内容

WHEN 条件就是一个布尔表达式 — 与您在 WHERE 子句中编写的表达式相同。您可以使用比较运算、AND、OR、BETWEEN、IN、LIKE 等。

SELECT email,
       CASE WHEN country IN ('US','CA') AND age >= 18 THEN 'eligible'
            WHEN email LIKE '%@test.com'             THEN 'test account'
            ELSE 'review'
       END AS segment
FROM users;

结果类型必须兼容

CASE 的每个分支都必须返回兼容类型的值,因为该列必须只有一种类型。混合文本和数字会导致错误或意外的类型转换。

如果一个分支需要数字、另一个分支需要文本,请显式进行类型转换,使类型保持一致。

SELECT product_id,
       CASE WHEN on_sale THEN price * 0.9
            ELSE price
       END AS effective_price   -- all branches numeric: good
FROM products;

在 WHERE 中使用 CASE

由于 CASE 会生成一个值,因此您可以在 WHERE 子句中比较它的结果。这对于动态筛选规则很有用。

不过,通常在 WHERE 中直接使用布尔逻辑更清晰 — 只有在分支确实能简化条件时,才在 WHERE 中使用 CASE。

SELECT *
FROM orders
WHERE CASE WHEN priority = 'high' THEN total > 0
           ELSE total > 500
      END;

嵌套 CASE

您可以将一个 CASE 放在另一个 CASE 分支中,以表达分层逻辑。这样做可行,但嵌套过深的表达式会变得难以阅读。

请保持浅层嵌套;如果嵌套逐渐变深,单独的列或查找表通常更清晰。

SELECT order_id,
       CASE WHEN region = 'EU' THEN
              CASE WHEN total > 100 THEN 'EU big'
                   ELSE 'EU small' END
            ELSE 'other'
       END AS bucket
FROM orders;

CASE 与聚合函数

一种强大的模式是:将 CASE 包裹在 SUM 或 COUNT 等聚合函数中。这样可以在一次遍历中有条件地统计或汇总行,有时也称为条件聚合或透视。

SELECT
  COUNT(*) AS total_orders,
  SUM(CASE WHEN status = 'shipped' THEN 1 ELSE 0 END) AS shipped,
  SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending
FROM orders;

CASE 有意返回 NULL

让分支返回 NULL 有时正是您需要的结果 — 例如,将不希望显示的值留空,或将其提供给会忽略 NULL 的后续聚合函数。

这里,只有大额订单保留其总额;其他订单变为 NULL,因此 AVG 会跳过它们。

SELECT order_id,
       CASE WHEN total >= 1000 THEN total
            ELSE NULL
       END AS large_order_total
FROM orders;

快速检查

请考虑以下针对 total = 1500 的行的表达式:

CASE WHEN total >= 100 THEN 'medium' WHEN total >= 1000 THEN 'large' ELSE 'small' END

它会返回什么值?

回顾:CASE 表达式

您学习了 SQL 中条件逻辑的核心:

  • CASE WHEN ... THEN ... ELSE ... END 为每行返回一个值
  • 分支从上到下进行检查;第一个匹配项优先
  • 省略 ELSE 时,如果没有任何匹配项,则返回 NULL
  • 所有分支都必须返回兼容的类型
  • CASE 可用于 SELECT、WHERE 以及聚合函数内部

接下来,我们将比较 CASE 的两种语法形式。

SELECT name,
       CASE WHEN price > 100 THEN 'expensive'
            WHEN price > 20  THEN 'mid'
            ELSE 'cheap'
       END AS tier
FROM products;

常见问题解答

「CASE 表达式」课时是免费的吗?

是的 — 「CASE 表达式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。

「CASE 表达式」这节课中我会学到什么?

在查询中使用 IF/THEN 逻辑 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 SQL Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「CASE 表达式」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 SQL Academy 课中编写并运行代码吗?

能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. CASE 表达式
  2. 搜索式 CASE 与简单 CASE
  3. 数据分桶与标注
  4. ORDER BY 和聚合中的 CASE
← 返回 SQL Academy