在前面介紹的使用SQL語句執行查詢操作時,我們可能發現查詢出的數據結果的排序是無序的。為了更好的觀察數據表中的查詢結果,開發人員或者用戶經常要對查詢的數據進行排序操作,這就需要使用ORDER BY子句。在數據庫的實際應用中,有時需要對查詢的數據進行統計和分組操作,這就需要了解SQL語句的聚合函數和GROUP BY子句的使用。有些時候開發人員或者用戶還希望對分組後的結果做進一步的統計,在SQL語句中提供了ROLLUP這樣一個關鍵字用來對數據進行統計。最後還將介紹主要數據庫中如何限制結果集的行數。
1.使用ORDER BY子句對數據記錄進行排序
指定表中的一列進行排序
通過ORDER BY 子句可以對查詢結果中指定的列進行升序或者是降序操作,這取決於ORDER BY子句後的關鍵字,如果ORDER BY子句後面的關鍵字是ASC,則對查詢的結果執行升序操作;如果ORDER BY子句後面的關鍵字是DESC,則對查詢的結果執行降序操作。其語法規則如下
ORDER BY 列名1 [ASC|DESC]
其中列名1表示需要對該列進行排序操作。關鍵字ASC和DESC是可選的。如果ORDER BY 子句後面不寫ASC或者是DESC,則默認執行的是升序操作。
dept salary
指定表中列的位置序號進行排序
排在使用ORDER BY子句進行排序操作時,除了可以使用列名對指定列進行序,也可以使用該列在選擇列表中的位置的序號對其進行排序。
對SELECT語句中的非選擇列進行排序
ORDER BY子句中也可以對沒有在SELECT語句中出現的選擇列進行排序操作。
dept salary
指定表中的多列進行排序
ORDER BY子句除了可以指定單列進行排序操作,也可以指定數據表中的多個列進行排序操作。如果要指定數據表中的多個列進行排序操作,則指定排序的列與列之間需要用逗號隔開。其語法規則如下:
ORDER BY 列名1[ASC|DESC],列名2 [ASC|DESC]
其中列名1和列名2表示需要對指定的數據列進行排序操作。列名1和列名2之間用逗號進行分割。關鍵字ASC和DESC是可選的。如果ORDER BY 子句後面不寫ASC或者DESC,則默認執行的是升序操作。首先,根據ORDER BY中指定的第一列進行排序;然後,再根據ORDER BY子句中指定的第二列的升序或者降序方式進行排序。
salary ,dept
2.常用的聚合函數
聚合函數也被稱為分組函數或者統計函數,主要用於對得到的一組數據進行統計計算,例如求和、求平均值等,常用的聚合函數包括COUNT、MAX、MIN、SUM和AVG五個。
COUNT、SUM和AVG函數中可以使用DISTINCT關鍵字去除指定列中的重復項。使用DISTINCT關鍵字後只是對不同行的值進行統計。
MAX和MIN函數中的列或者表達式可以是數字型、字符型或者是日期類型的值。如果MAX和MIN函數中的列或者表達式是字符型的,則按照首字母從A到Z的順序排序,如果首字母相同,則比較字符串中第二個字母的大小,以此類推。漢字則是按照其漢語拼音的全拼來排序。
(salary), T_teacher
SUM和AVG函數中的表達式只能是數字類型的值。
除了COUNT(*)之外,其他的幾個函數在計算時都忽略表達式中的空值(NULL行)。
COUNT函數是用來計算數據表中的總行數,SUM函數是用來計算數據表中某一列的屬性值的總和。
(salary),(salary), T_teacher
聚合函數只能出現在SELECT語句、GROUP BY子句以及HAVING子句中,WHERE子句中不能出現聚合函數。
3.使用GROUP BY子句對表中數據進行分組
單列分組
使用GROUP BY子句對數據表中的某一列進行分組時,會對指定分組的列中不同的值都計算出一個統計結果。其語法格式如下:
GROUP BY列名1
其中列名1表示需要對該列進行分組操作。
dept, dept
Select同時包含數據列和聚合函數時,必須使用Group By。
多列分組
使用GROUP BY子句對數據表中的多個列進行分組時,會對指定分組的多個列中不同的值都計算出一個統計結果。其語法格式如下:
GROUP BY列名1,列名2…
其中列名1和列名2表示需要對指定列進行分組操作。列名1和列名2之間用逗號進行分割。
使用HAVING子句子限制分組後的查詢結果
如果想要對分組後的結果限制查詢條件,就需要使用HAVING子句。由於HAVING子句是用來限制分組後的查詢結果,所以該子句需要放到GROUP BY子句的後面使用。其語法格式如下:
GROUP BY列名1 HAVING 條件表達式
其中列名1表示需要對該列進行分組操作。HAVING子句後的條件表達式是用來篩選分組後的結果。在HAVING子句中經常使用聚合函數對分組後的結果進行篩選。
dept,profession, (salary)注意:GROUP BY下才有HAVING,HAVING用於組;而WHERE是針對SELECT的(針對於表或者視圖),WHERE用於分布前。
profession, age (salary)
對分組結果進行排序
很多時候,對數據表中數據進行分組後,還希望對分組的結果進行排序操作。如果想對使用了GROUP BY子句的分組結果進行排序的話,就需要使用ORDER BY子句。
dept,profession, (salary)
按照GROUP BY後分得的各組中的最高工資給組排序;而如下語句則是按照每組的第一行的工資給組排序。
dept,profession, salary
GROUP BY子句中處理NULL值
在使用GROUP BY子句對對指定列進行分組時,有時可能會遇到指定列中含有NULL值的情況。此時,GROUP BY子句會將該列中所有的NULL值歸為一組。
如果要得到每個分組中的工資的最大值對應的行(而不是分組的第一行),可以使用子查詢等方法,詳細以後討論。
( t_teacher salary ) salary
4.使用ROLLUP關鍵字統計數據
在實際應用中,有時不僅需要得到分組後的統計結果,還希望對分組的統計結果做進一步的計算,例如通過對教師信息表(T_teacher)中的院校和教師職稱進行分組,得到分組後教師的工資,還希望對每一個院系中的教師的工資做一個階段性的統計,希望得到各個院校中不同職稱的教師的工資的加和(相當於小計),還希望得到所有院校不同職稱教師工資的總和(相當於總計)。這個時候僅僅使用GROUP BY子句是無法做到的,此時就需要使用ROLLUP關鍵字。
ROLLUP關鍵字使用時需要放到GROUP BY關鍵字的後面。ROLLUP關鍵字在不同的數據庫中的使用方式上稍有不同。
a.在MySQL和Microsoft SQL Server數據庫中需要使用WITH ROLLUP。其語法格式如下:
列名1 ROLLUP
其中列名1表示要對該列進行分組,WITH ROLLUP關鍵字表示要對分組的結果進行統計。當然也可以對多個列進行分組,並統計分組後的結果。其語法格式如下:
GROUP BY 列名1 ,列名2 WITH ROLLUP
b.在Oracle數據庫中,ROLLUP關鍵字需要緊跟在GROUP BY關鍵字的後面,然後再寫需要分組的字段。其語法格式如下:
GROUP BY ROLLUP (列名1,列名2…)
5.限制結果集行數
有些時候,開發人員或者用戶並不希望將查詢結果的數據列中的數據全部顯示出來,而是只希望顯示其中的幾行,尤其是在需要分頁的操作中。例如,一個數據表最後查詢出了100條記錄,而開發人員或者用戶只關心其中前10條記錄的值,這就需要對查詢結果中的數據記錄的行數進行限制。在不同的數據庫中限制結果集行數的方法也不盡相同。
a.在MySQL數據庫中限制結果集行數可以使用LIMIT關鍵字,它可以用來限制查詢出來的數據結果的個數。通過使用LIMIT關鍵字可以讓開發人員或者用戶得到其中想要的部分的結果。如果要使用LIMIT限制結果集行數,可以使用下面的語法格式。
LIMIT n
其中LIMIT是關鍵字,數字n表示要限制結果集行數。
LIMIT ,
b.Oracle數據庫中不支持類似於 MySQL 中的 LIMIT關鍵字來限制結果集行數,但是在 Oracle數據庫中可以使用ROWNUM關鍵字限制結果集的行數。其語法格式如下:
WHERE ROWNUM<n
其中ROWNUM關鍵字表示對符合條件結果的序列號,它的起始值總是從1開始的。數字n表示要限制的結果集的行數。當然,這裡的比較運算符除了可以使用(<)小於以外,還可以使用(<=)小於等於。
c.MySQL數據庫和Oracle數據庫中使用LIMIT關鍵字和ROWNUM的方法限制結果集行數,在Microsoft SQL Server數據庫中需要使用TOP關鍵字。其語法格式如下:
SELECT TOP n [PRECENT] 列名1,列名2 …
FROM 表名
…
其中,TOP是表示限制結果集行數的關鍵字;數字n表示限制結果集行數;PRECENT關鍵字表示返回查詢的結果集中前n%的行數,它是可選的。