目錄
- 一、ORDER BY 子句
- 二、指定升序或降序
- 三、指定多個排序鍵
- 四、NULL 的順序
- 五、在排序鍵中使用顯示用的別名
- 六、ORDER BY 子句中可以使用的列
- 七、不要使用列編號
- 請參閱
學習重點
使用
ORDER BY子句對查詢結果進行排序,在
ORDER BY子句中列名的后面使用關鍵字ASC可以進行升序排序,使用DESC關鍵字可以進行降序排序,
ORDER BY子句中可以指定多個排序鍵,排序健中包含
NULL時,會在開頭或末尾進行匯總,
ORDER BY子句中可以使用SELECT子句中定義的列的別名,
ORDER BY子句中可以使用SELECT子句中未出現的列或者聚合函式,
ORDER BY子句中不能使用列的編號,
一、ORDER BY 子句
截至目前,我們使用了各種各樣的條件對表中的資料進行查詢,本節讓我們再來回顧一下簡單的 SELECT 陳述句(代碼清單 27),
代碼清單 27 顯示商品編號、商品名稱、銷售單價和進貨單價的 SELECT 陳述句
SELECT product_id, product_name, sale_price, purchase_price
FROM Product;
執行結果
product_id | product_name | sale_price | purchase_price
------------+---------------+--------------+----------------
0001 | T恤衫 | 1000 | 500
0002 | 打孔器 | 500 | 320
0003 | 運動T恤 | 4000 | 2800
0004 | 菜刀 | 3000 | 2800
0005 | 高壓鍋 | 6800 | 5000
0006 | 叉子 | 500 |
0007 | 擦菜板 | 880 | 790
0008 | 圓珠筆 | 100 |
對于上述結果,在此無需特別說明,本節要為大家介紹的不是查詢結果,而是查詢結果的排列順序,
那么,結果中的 8 行記錄到底是按照什么順序排列的呢?乍一看,貌似是按照商品編號從小到大的順序(升序)排列的,其實,排列順序是隨機的,這只是個偶然,因此,再次執行同一條 SELECT 陳述句時,順序可能大為不同,
KEYWORD
- 升序
通常,從表中抽取資料時,如果沒有特別指定順序,最終排列順序便無從得知,即使是同一條 SELECT 陳述句,每次執行時排列順序很可能發生改變,
但是不進行排序,很可能出現結果混亂的情況,這時,便需要通過在 SELECT 陳述句末尾添加 ORDER BY 子句來明確指定排列順序,
KEYWORD
ORDER BY子句
ORDER BY 子句的語法如下所示,
語法 4 ORDER BY 子句
SELECT <列名1>, <列名2>, <列名3>, ……
FROM <表名>
ORDER BY <排序基準列1>, <排序基準列2>, ……
例如,按照銷售單價由低到高,也就是升序排列時,請參見代碼清單 28,
代碼清單 28 按照銷售單價由低到高(升序)進行排列
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price;
執行結果

不論何種情況,ORDER BY 子句都需要寫在 SELECT 陳述句的末尾,這是因為對資料行進行排序的操作必須在結果即將回傳時執行,ORDER BY 子句中書寫的列名稱為排序鍵,該子句與其他子句的順序關系如下所示,
KEYWORD
- 排序鍵
? 子句的書寫順序
SELECT子句 → 2.FROM子句 → 3.WHERE子句 → 4.GROUP BY子句 → 5.HAVING子句 → 6.ORDER BY子句
法則 15
ORDER BY子句通常寫在 SELECT 陳述句的末尾,
不想指定資料行的排列順序時,SELECT 陳述句中不寫 ORDER BY 子句也沒關系,
二、指定升序或降序
與上述示例相反,想要按照銷售單價由高到低,也就是降序排列時,可以參見代碼清單 29,在列名后面使用 DESC 關鍵字,
KEYWORD
降序
DESC關鍵字
代碼清單 29 按照銷售單價由高到低(降序)進行排列
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price DESC;
執行結果
product_id | product_name | sale_ price | purchase_ price
------------+--------------+-------------+----------------
0005 | 高壓鍋 | 6800 | 5000
0003 | 運動T恤 | 4000 | 2800
0004 | 菜刀 | 3000 | 2800
0001 | T恤衫 | 1000 | 500
0007 | 擦菜板 | 880 | 790
0002 | 打孔器 | 500 | 320
0006 | 叉子 | 500 |
0008 | 圓珠筆 | 100 |
如上所示,這次銷售單價最高(6800 日元)的高壓鍋排在了第一位,其實,使用升序進行排列時,正式的書寫方式應該是使用關鍵字 ASC,但是省略該關鍵字時會默認使用升序進行排序,這可能是因為實際應用中按照升序排序的情況更多吧,ASC 和 DESC 是 ascendent(上升的)和 descendent(下降的)這兩個單詞的縮寫,
KEYWORD
ASC關鍵字
法則 16
未指定
ORDER BY子句中排列順序時會默認使用升序進行排列,
由于 ASC 和 DESC 這兩個關鍵字是以列為單位指定的,因此可以同時指定一個列為升序,指定其他列為降序,
三、指定多個排序鍵
本節開頭曾提到過對銷售單價進行升序排列的 SELECT 陳述句(代碼清單 28)的執行結果,我們再來回顧一下,可以發現銷售單價為 500 日元的商品有 2 件,相同價格的商品的順序并沒有特別指定,或者可以說是隨機排列的,
如果想要對該順序的商品進行更細致的排序的話,就需要再添加一個排序鍵,在此,我們以添加商品編號的升序為例,請參見代碼清單 30,
代碼清單 30 按照銷售單價和商品編號的升序進行排序
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price, product_id;
執行結果

這樣一來,就可以在 ORDER BY 子句中同時指定多個排序鍵了,規則是優先使用左側的鍵,如果該列存在相同值的話,再接著參考右側的鍵,當然,也可以同時使用 3 個以上的排序鍵,
四、NULL 的順序
在此前的示例中,我們已經使用過銷售單價(sale_price 列)作為排序鍵了,這次讓我們嘗試使用進貨單價(purchase_price 列)作為排序鍵吧,此時,問題來了,圓珠筆和叉子對應的值是 NULL,究竟 NULL 會按照什么順序進行排列呢? NULL 是大于 100 還是小于 100 呢?或者說 5000 和 NULL 哪個更大呢?
請大家回憶一下我們在 算術運算子和比較運算子 中學過的內容,沒錯,不能對 NULL 使用比較運算子,也就是說,不能對 NULL 和數字進行排序,也不能與字串和日期比較大小,因此,使用含有 NULL 的列作為排序鍵時, NULL 會在結果的開頭或末尾匯總顯示(代碼清單 31),
代碼清單 31 按照進貨單價的升序進行排列
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY purchase_price;
執行結果

究竟是在開頭顯示還是在末尾顯示,并沒有特殊規定,某些 DBMS 中可以指定 NULL 在開頭或末尾顯示,希望大家對自己使用的 DBMS 的功能研究一下,
法則 17
排序鍵中包含
NULL時,會在開頭或末尾進行匯總,
五、在排序鍵中使用顯示用的別名
在 對表進行分組 中“常見錯誤 ②”中曾介紹過,在 GROUP BY 子句中不能使用 SELECT 子句中定義的別名,但是在 ORDER BY 子句中卻是允許使用別名的,因此,代碼清單 32 中的 SELECT 陳述句并不會出錯,可正確執行,
代碼清單 32 ORDER BY 子句中可以使用列的別名
SELECT product_id AS id, product_name, sale_price AS sp, purchase_price
FROM Product
ORDER BY sp, id;
上述 SELECT 陳述句與之前按照“銷售單價和商品編號的升序進行排列”的 SELECT 陳述句(代碼清單 31)意思完全相同,
執行結果
id | product_name | sp | purchase_price
------+---------------+-------+---------------
0008 | 圓珠筆 | 100 |
0002 | 打孔器 | 500 | 320
0006 | 叉子 | 500 |
0007 | 擦菜板 | 880 | 790
0001 | T恤衫 | 1000 | 500
0004 | 菜刀 | 3000 | 2800
0003 | 運動T恤 | 4000 | 2800
0005 | 高壓鍋 | 6800 | 5000
不能在 GROUP BY 子句中使用的別名,為什么可以在 ORDER BY 子句中使用呢?這是因為 SQL 陳述句在 DBMS 內部的執行順序被掩蓋起來了,SELECT 陳述句按照子句為單位的執行順序如下所示,
? 使用 HAVING 子句時 SELECT 陳述句的順序
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
這只是一個粗略的總結,雖然具體的執行順序根據 DBMS 的不同而不同,但是大家有這樣一個大致的印象就可以了,一定要記住 SELECT 子句的執行順序在 GROUP BY 子句之后,ORDER BY 子句之前,因此,在執行 GROUP BY 子句時,SELECT 陳述句中定義的別名無法被識別 [1],對于在 SELECT 子句之后執行的 ORDER BY 子句來說,就沒有這樣的問題了,
法則 18
在
ORDER BY子句中可以使用SELECT子句中定義的別名,
六、ORDER BY 子句中可以使用的列
ORDER BY 子句中也可以使用存在于表中、但并不包含在 SELECT 子句之中的列(代碼清單 33),
代碼清單 33 SELECT 子句中未包含的列也可以在 ORDER BY 子句中使用
SELECT product_name, sale_price, purchase_price
FROM Product
ORDER BY product_id;
執行結果
product_name | sale_price | purchase_price
---------------+-------------+----------------
T恤衫 | 1000 | 500
打孔器 | 500 | 320
運動T恤 | 4000 | 2800
菜刀 | 3000 | 2800
高壓鍋 | 6800 | 5000
叉子 | 500 |
擦菜板 | 880 | 790
圓珠筆 | 100 |
除此之外,還可以使用聚合函式(代碼清單 34),
代碼清單 34 ORDER BY 子句中也可以使用聚合函式

執行結果
product_type | count
---------------+------
衣服 | 2
辦公用品 | 2
廚房用具 | 4
法則 19
在
ORDER BY子句中可以使用SELECT子句中未使用的列和聚合函式,
七、不要使用列編號
在 ORDER BY 子句中,還可以使用在 SELECT 子句中出現的列所對應的編號,是不是沒想到?列編號是指 SELECT 子句中的列按照從左到右的順序進行排列時所對應的編號(1, 2, 3,…),因此,代碼清單 35 中的兩條 SELECT 陳述句的含義是相同的,
KEYWORD
- 列編號
代碼清單 35 ORDER BY 子句中可以使用列的編號
-- 通過列名指定
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY sale_price DESC, product_id;
-- 通過列編號指定
SELECT product_id, product_name, sale_price, purchase_price
FROM Product
ORDER BY 3 DESC, 1;
上述第 2 條 SELECT 陳述句中的 ORDER BY 子句所代表的含義,就是“按照 SELECT 子句中第 3 列的降序和第 1 列的升序進行排列”,這和第 1 條 SELECT 陳述句的含義完全相同,
執行結果
product_id | product_name | sale_price | purchase_price
-----------+---------------+-------------+----------------
0005 | 高壓鍋 | 6800 | 5000
0003 | 運動T恤 | 4000 | 2800
0004 | 菜刀 | 3000 | 2800
0001 | T恤衫 | 1000 | 500
0007 | 擦菜板 | 880 | 790
0002 | 打孔器 | 500 | 320
0006 | 叉子 | 500 |
0008 | 圓珠筆 | 100 |
雖然列編號使用起來非常方便,但我們并不推薦使用,原因有以下兩點,
第一,代碼閱讀起來比較難,使用列編號時,如果只看 ORDER BY 子句是無法知道當前是按照哪一列進行排序的,只能去 SELECT 子句的串列中按照列編號進行確認,上述示例中 SELECT 子句的列數比較少,因此可能并沒有什么明顯的感覺,但是在實際應用中往往會出現列數很多的情況,而且 SELECT 子句和 ORDER BY 子句之間,還可能包含很復雜的 WHERE 子句和 HAVING 子句,直接人工確認實在太麻煩了,
第二,這也是最根本的問題,實際上,在 SQL-92 [2] 中已經明確指出該排序功能將來會被洗掉,因此,雖然現在使用起來沒有問題,但是將來隨著 DBMS 的版本升級,可能原本能夠正常執行的 SQL 突然就會出錯,不光是這種單獨使用的 SQL 陳述句,對于那些在系統中混合使用的 SQL 來說,更要極力避免,
法則 20
在
ORDER BY子句中不要使用列編號,
請參閱
- 對表進行聚合查詢
- 對表進行分組
- 為聚合結果指定條件
- 對查詢結果進行排序
(完)
也是因為這一原因,
HAVING子句也不能使用別名, ??1992 年制定的 SQL 標準, ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/374430.html
標籤:SQL Server
