ORDER BY 和聚合中的 CASE
实现条件排序和计数
ORDER BY 和聚合中的 CASE 是 CoddyKit 上的免费 SQL Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 SQL Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 SQL Academy 课程共包含 4 节课。
按自定义优先级排序
SQL 的 ORDER BY 子句通常按列的自然值对行排序。但您可以在 ORDER BY 中嵌入 CASE 表达式,创建完全自定义的排序顺序——这是任何单个列都无法独自实现的顺序。
当优先级由业务规则而非原始数据值决定时,这项技术非常有用。
SELECT product_name, status
FROM products
ORDER BY
CASE status
WHEN 'urgent' THEN 1
WHEN 'active' THEN 2
WHEN 'pending' THEN 3
ELSE 4
END;CASE 在 ORDER BY 中的工作方式
数据库计算 ORDER BY CASE ... END 时,会为每一行计算一个整数(或任何可比较的值)。随后,行会按照这个计算出的值排序,而不是按照原始列排序,或者在此基础上进一步排序。
CASE 表达式不会被存储;它只在查询执行期间存在。
SELECT order_id, priority
FROM orders
ORDER BY
CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 9
END,
order_id;显式排序 NULL
默认情况下,不同数据库会以不同方式将 NULL 放在排序结果的开头或末尾。ORDER BY 中的 CASE 允许您准确决定 NULL 的位置——无论使用哪种数据库引擎。
SELECT employee_name, manager_id
FROM employees
ORDER BY
CASE WHEN manager_id IS NULL THEN 0 ELSE 1 END,
manager_id;条件升序与降序
ORDER BY 中的 CASE 还可以模拟条件排序方向。通过将类别值映射为负数,您可以有效地反转特定分组的排序顺序,同时让其他分组保持正常顺序。
当单个结果集中的不同类型行需要不同的排序逻辑时,这种方法非常有用。
SELECT task_name, due_date, is_overdue
FROM tasks
ORDER BY
CASE WHEN is_overdue = 1 THEN 0 ELSE 1 END,
due_date;COUNT 中的 CASE
您可以在 COUNT 等聚合函数中嵌入 CASE 表达式。诀窍是:对想要计数的行返回非 NULL 值,对想要跳过的行返回 NULL——因为 COUNT 会忽略 NULL。
SELECT
COUNT(CASE WHEN status = 'active' THEN 1 END) AS active_count,
COUNT(CASE WHEN status = 'inactive' THEN 1 END) AS inactive_count
FROM users;SUM 中的 CASE——条件总计
将 CASE 放入 SUM 中,可以仅在条件为真时累加值,并将不匹配的行视为零。这是透视样式报表中非常常见的模式,可将一个列拆分为多个指标列。
SELECT
SUM(CASE WHEN region = 'North' THEN sales_amount ELSE 0 END) AS north_total,
SUM(CASE WHEN region = 'South' THEN sales_amount ELSE 0 END) AS south_total,
SUM(CASE WHEN region = 'East' THEN sales_amount ELSE 0 END) AS east_total
FROM sales;使用 CASE 进行条件 AVG
同样的模式适用于 AVG。由于 AVG 会忽略 NULL,对想要排除的行返回 NULL,就能得到仅包含匹配行的平均值——无需子查询。
SELECT
AVG(CASE WHEN department = 'Engineering' THEN salary END) AS avg_eng_salary,
AVG(CASE WHEN department = 'Marketing' THEN salary END) AS avg_mkt_salary
FROM employees;使用 CASE 分组——对行进行分桶
您可以在 GROUP BY 或 SELECT 列表中使用 CASE,将连续值分成多个类别,然后对每个分桶进行聚合。这样可以在不更改底层数据的情况下,将数值列转换为带标签的分组。
SELECT
CASE
WHEN age < 18 THEN 'Under 18'
WHEN age BETWEEN 18 AND 35 THEN '18-35'
WHEN age BETWEEN 36 AND 55 THEN '36-55'
ELSE '56+'
END AS age_group,
COUNT(*) AS user_count
FROM users
GROUP BY
CASE
WHEN age < 18 THEN 'Under 18'
WHEN age BETWEEN 18 AND 35 THEN '18-35'
WHEN age BETWEEN 36 AND 55 THEN '36-55'
ELSE '56+'
END;使用别名与重复 CASE 的对比
在 SELECT 和 GROUP BY 中重复冗长的 CASE 表达式会使语句很繁琐。某些数据库(MySQL,以及通过变通方法实现的 PostgreSQL)允许您在 ORDER BY 中引用别名,但不能在 GROUP BY 中引用。最安全、可移植的方法是将查询包装在子查询或 CTE 中,然后在那里按别名执行 GROUP BY。
WITH scored AS (
SELECT
customer_id,
CASE
WHEN total_spent >= 1000 THEN 'Gold'
WHEN total_spent >= 500 THEN 'Silver'
ELSE 'Bronze'
END AS tier
FROM customers
)
SELECT tier, COUNT(*) AS customer_count
FROM scored
GROUP BY tier
ORDER BY
CASE tier
WHEN 'Gold' THEN 1
WHEN 'Silver' THEN 2
ELSE 3
END;组合使用 ORDER BY CASE 与 ASC / DESC
在 CASE 表达式后,仍然可以追加 ASC 或 DESC,并用逗号分隔添加更多排序列。CASE 得分只是第一个排序键;后续列会按通常方式打破并列。
SELECT
ticket_id,
category,
created_at
FROM support_tickets
ORDER BY
CASE category
WHEN 'billing' THEN 1
WHEN 'outage' THEN 2
WHEN 'feature' THEN 3
ELSE 4
END ASC,
created_at ASC;真实案例——销售仪表板
下面是一个贴近实际的查询,它将基于 CASE 的聚合与基于 CASE 的排序结合起来。该查询会生成按地区汇总的销售摘要,并按收入从高到低排序,使收入最高的地区始终排在最前面,同时将“其他”排到最后。
SELECT
CASE
WHEN region IN ('North', 'South', 'East', 'West') THEN region
ELSE 'Other'
END AS region_label,
SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END) AS completed_sales,
COUNT(CASE WHEN status = 'refunded' THEN 1 END) AS refund_count
FROM orders
GROUP BY
CASE
WHEN region IN ('North', 'South', 'East', 'West') THEN region
ELSE 'Other'
END
ORDER BY completed_sales DESC;知识检查
检验您对在 ORDER BY 和聚合函数中使用 CASE 的理解。
课程回顾
在本课中,您学习了如何将 CASE 与 ORDER BY 和聚合函数结合使用:
- ORDER BY 中的 CASE — 为各行分配自定义排序分数,控制 NULL 的显示位置,并在一个查询中组合多条排序规则。
- COUNT 中的 CASE — 对要包含的行返回非 NULL 值,对要跳过的行隐式或显式地返回 NULL。
- SUM / AVG 中的 CASE — 使用 0 或 NULL 作为 ELSE 值,在一次遍历中构建条件总计和平均值。
- GROUP BY 中的 CASE — 将连续值或类别值划分到带标签的分组中,以便进行聚合。
这些模式可以消除许多子查询,让您能够直接使用 SQL 简洁地编写透视表式报表。
用 AI 导师学习 SQL — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 46
- 课程
- 183
常见问题解答
「ORDER BY 和聚合中的 CASE」课时是免费的吗?
是的 — 「ORDER BY 和聚合中的 CASE」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 SQL Academy 课程的其余内容,请升级到 CoddyKit PRO。 SQL Academy 课程共包含 4 节课。
「ORDER BY 和聚合中的 CASE」这节课中我会学到什么?
实现条件排序和计数 你通过在浏览器中直接运行的动手代码来练习 SQL Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 SQL Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 SQL Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「ORDER BY 和聚合中的 CASE」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 SQL Academy 课中编写并运行代码吗?
能。每节 SQL Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- CASE 表达式
- 搜索式 CASE 与简单 CASE
- 数据分桶与标注
- ORDER BY 和聚合中的 CASE