前面學了很多篩選條件的布林運算子,但那些都還是在 WHERE 裡面用的。
現在終於要學一個新的指令了:ORDER BY(排序)。
排序在日常生活中很常見,誰的收入比較高?誰的成績比較好?這些都是排序。
在資料庫中,排序也是整理資料的重要方式。
排序需要回答三個問題
假設老闆說:「請你幫我把會員排序一下。」
你聽到這個要求,應該會問三個問題:
- 按照什麼排?(欄位)
- 是按照姓氏排嗎?還是按照生日?還是按照年收入?
- 正的排還是反的排?(方向)
- 是從小到大(遞增)?還是從大到小(遞減)?
- 空值要放哪裡?(NULL 的位置)
- 如果有些資料是 NULL,要放在最前面還是最後面?
這三個問題,就是 ORDER BY 要回答的事情。
ORDER BY 的基本語法
ORDER BY 的意思是「根據…排序」。
ORDER BY 欄位名稱指定排序方向
- ASC(Ascending):遞增,從小到大,這是預設值,可以不寫
- DESC(Descending):遞減,從大到小
-- 遞增排序(預設,可以不寫 ASC)
ORDER BY 年齡 ASC
ORDER BY 年齡
-- 遞減排序(要寫 DESC)
ORDER BY 年齡 DESC怎麼記?
- ASC:A 像一個往上的箭頭 ↑,代表往上、遞增
- DESC:想到 decrease(減少),代表往下、遞減
指定 NULL 的位置
大部分資料庫會自動幫你決定 NULL 要放哪裡,通常不用特別指定。
但如果需要的話,可以用:
- NULLS FIRST:空值放最前面
- NULLS LAST:空值放最後面
ORDER BY 年齡 DESC NULLS LASTORDER BY 在執行計畫中的位置
學一個新指令的時候,要問一個重要的問題:它在執行計畫中排在什麼位置?
想像一下,如果你自己手動整理資料,你會先排序再計算,還是先計算再排序?
答案是:先計算,再排序。
為什麼?因為很多時候,你要排序的欄位是計算出來的結果。
比如說,你想按照「含稅價」排序,但「含稅價」是用 單價 * 1.05 算出來的。
如果還沒算出含稅價,你根本不知道要怎麼排。
所以 ORDER BY 一定要在 SELECT 之後執行。
完整的執行順序:
| 順序 | 指令 | 做的事情 |
|---|---|---|
| 1 | FROM | 拿出表單 |
| 2 | WHERE | 篩選資料 |
| 3 | SELECT | 計算、輸出欄位 |
| 4 | ORDER BY | 排序 |
為什麼執行順序很重要?
因為這會影響到別名能不能用。
舉個例子:
SELECT 名稱, 單價 * 1.05 AS 含稅價
FROM 商品
ORDER BY 含稅價 DESC在這個查詢中,含稅價 是在 SELECT 裡面定義的別名。
可以在 ORDER BY 用這個別名嗎?
可以!
因為 ORDER BY 在 SELECT 之後執行,這時候別名已經定義好了。
可以在 WHERE 用這個別名嗎?
不行!
因為 WHERE 在 SELECT 之前執行,這時候別名還沒定義。
-- ✓ 正確:ORDER BY 可以用 SELECT 的別名
SELECT 單價 * 1.05 AS 含稅價
FROM 商品
ORDER BY 含稅價 DESC
-- ✗ 錯誤:WHERE 不能用 SELECT 的別名
SELECT 單價 * 1.05 AS 含稅價
FROM 商品
WHERE 含稅價 > 100 -- 這會出錯!理解執行順序,你就不用死背這些規則了。
多欄位排序
如果兩筆資料的排序欄位值一樣,怎麼辦?
可以指定第二個排序欄位:
ORDER BY 單價 DESC, 庫存 ASC這表示:
- 先按照「單價」從高到低排
- 如果單價一樣,再按照「庫存」從少到多排
舉個例子,假設有這張商品表單:
| 名稱 | 單價 | 庫存 |
|---|---|---|
| 蘋果 | 30 | 100 |
| 香蕉 | 30 | 50 |
| 牛奶 | 50 | 200 |
| 果汁 | 40 | 80 |
按照 ORDER BY 單價 DESC, 庫存 ASC 排序後:
| 名稱 | 單價 | 庫存 |
|---|---|---|
| 牛奶 | 50 | 200 |
| 果汁 | 40 | 80 |
| 香蕉 | 30 | 50 |
| 蘋果 | 30 | 100 |
先看第一個條件:單價從高到低。
牛奶(50 元)→ 果汁(40 元)→ 蘋果和香蕉(都是 30 元)
蘋果和香蕉的單價一樣,怎麼辦?
看第二個條件:庫存從少到多。
香蕉的庫存(50)比蘋果(100)少,所以香蕉排在蘋果前面。
小結
這篇文章介紹了 ORDER BY 排序:
- 排序要回答三個問題:按什麼欄位排、遞增還是遞減、NULL 放哪裡
- ASC 和 DESC:ASC 是遞增(預設),DESC 是遞減
- ORDER BY 在 SELECT 之後執行:所以可以用 SELECT 定義的別名
- 多欄位排序:用逗號隔開,第一個欄位相同時,看第二個欄位
理解執行順序,你就知道為什麼別名在某些地方能用、某些地方不能用,不用死背規則。