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
ENDCASE 返回一个值
关键概念是: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 反馈 — 无需本地设置。