SQL 排序核心总结 (ORDER BY + ASC/DESC)
https://sqlzoo.net/wiki/SELECT_from_Nobel_Tutorial
1. 基本定义
| 关键字 | 含义 | 默认 | 排序方向 | 示例 |
|---|---|---|---|---|
ASC | 升序 (Ascending) | 是 | 从小到大 / 从早到晚 | A→Z 1→100 2000→2023 |
DESC | 降序 (Descending) | 否 | 从大到小 / 从晚到早 | Z→A 100→1 2023→2000 |
2.核心语法
SELECT 列1, 列2FROM 表名ORDER BY 排序列1 [ASC|DESC], -- 第一优先级 排序列2 [ASC|DESC] -- 第二优先级(当列1值相同时生效)3.经典例题
- Knights in order
List the winners, year and subject where the winner starts with Sir. Show the the most recent first, then by name order.
SELECT winner, yr, subjectFROM nobelWHERE winner LIKE 'Sir%' -- 筛选骑士ORDER BY yr DESC, winner ASC; -- 先年份降序,再姓名升序- 结果示例
| winner | yr | subject | 排序逻辑说明 |
|---|---|---|---|
| Sir Peter Ratcliffe | 2019 | Medicine | 年份最新 (2019) |
| Sir Gregory Winter | 2018 | Chemistry | ↓ 年份降序 |
| Sir Fraser Stoddart | 2016 | Chemistry | ↓ 年份降序 |
| Sir John Gurdon | 2012 | Medicine | 同2012年… |
| Sir Martin Evans | 2007 | Medicine | ↓ 年份降序 |
IN逻辑表达式在条件排序中的使用
-
核心思想: 在
ORDER BY子句中,利用CASE表达式为符合IN条件的行生成一个特定的值(比如0),为不符合条件的行生成另一个值(比如1)。然后首先按这个0/1值排序(升序),这样0(符合条件的)就自然排在了1(不符合条件的)前面。之后,你可以再按其他字段(如名称、ID等)进行二次排序。 -
为什么需要这个技巧? 默认情况下,
ORDER BY只是单纯地按照你指定的列升序或降序排列。它不会自动把WHERE IN (...)筛选出来的结果放在最前面。这个技巧就是为了强制让满足特定IN条件的结果集出现在查询结果的顶部。 -
语法和原理
SELECT 列1, 列2, ...FROM 表名WHERE ... -- 可选的过滤条件ORDER BY CASE WHEN 目标列 IN (值1, 值2, 值3, ...) THEN 0 -- 符合条件的给 0 ELSE 1 -- 不符合条件的给 1 END, -- 首先按这个 0/1 标志排序 (升序 ASC 是默认的, 所以 0 在前) 其他排序列1 [ASC|DESC], -- 然后按其他列排序 其他排序列2 [ASC|DESC];- 关键点解析
-
CASE表达式:-
WHEN 目标列 IN (...) THEN 0: 检查目标列的值是否在你指定的值列表中。如果是,返回0。 -
ELSE 1: 如果目标列的值不在指定的值列表中,返回1。 -
这个
CASE表达式为每一行计算出一个排序权重值 (0或1)。
-
-
ORDER BY子句:-
ORDER BY CASE ... END, ...: 排序的第一优先级就是这个计算出来的0/1权重值。 -
因为
ORDER BY默认是升序 (ASC),所以0会排在1的前面。所有符合IN条件的行(权重0)就会显示在最前面。 -
在权重值排序之后,你可以再按其他需要的列(比如
Name,ID,Date等)进行排序。这保证了在“符合条件的组”和“不符合条件的组”内部,数据也是有序的。
-
- 经典例题
The expression subject IN (‘chemistry’,‘physics’) can be used as a value - it will be 0 or 1. Show the 1984 winners and subject ordered by subject and winner name; but list chemistry and physics last.
- 思路:
- 使用表达式:
subject IN ('chemistry','physics')会为每条记录返回一个值:
-
如果subject是’chemistry’或’physics’,返回1(TRUE)
-
否则返回0(FALSE)
-
在ORDER BY子句中,我们首先按这个0/1值排序(升序,因为默认ASC,所以0在前,1在后)。这样非化学物理的(0)就会排在前,化学物理的(1)排在后。
-
然后,在同一个组内(比如都是0的组或都是1的组),再按subject(奖项名称)排序,最后按winner(获奖者姓名)排序。
-- 示例:判断结果SELECT winner, subjectFROM nobelWHERE yr = 1984ORDER BY subject IN ('chemistry','physics'), -- 先按0/1排序(0在前,1在后) subject, -- 然后按subject升序(A-Z) winner -- 最后按winner升序(A-Z)- 结果示例:
| winner | subject |
|---|---|
| Jaroslav Seifert | literature |
| César Milstein | medicine |
| GeorgesF. Köhler | medicine |
| Niels Jerne | medicine |
| Desmond Tutu | peace |
| Bruce Merrifield | chemistry |
| Carlo Rubbia | physics |
| Simon van der Meer | physics |