數據的排序與分組語句

數據的排序與分組語句

 

使用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,則默認執行的是升序操作。 

 

 

SELECT teaID,teaName,dept,profession,salary

FROM T_teacher 

WHERE dept ='計算機系'

ORDER BY salary ASC

 

指定表中列的位置序號進行排序 

排在使用ORDER BY子句進行排序操作時,除瞭可以使用列名對指定列進行序,也可以使用該列在選擇列表中的位置的序號對其進行排序。 

 

 

SELECT teaID,teaName,dept,profession,salary

FROM T_teacher 

ORDER BY 5 ASC

 

對SELECT語句中的非選擇列進行排序 

ORDER BY子句中也可以對沒有在SELECT語句中出現的選擇列進行排序操作。 

 

 

SELECT teaID,teaName,dept,profession

FROM T_teacher 

WHERE dept ='計算機系'

ORDER BY 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子句中指定的第二列的升序或者降序方式進行排序。 

 

 

SELECT teaID,teaName,dept,profession,salary

FROM T_teacher 

ORDER BY salary DESC,dept ASC

 

2.常用的聚合函數

 

聚合函數也被稱為分組函數或者統計函數,主要用於對得到的一組數據進行統計計算,例如求和、求平均值等,常用的聚合函數包括COUNT、MAX、MIN、SUM和AVG五個。 

COUNT、SUM和AVG函數中可以使用DISTINCT關鍵字去除指定列中的重復項。使用DISTINCT關鍵字後隻是對不同行的值進行統計。 

MAX和MIN函數中的列或者表達式可以是數字型、字符型或者是日期類型的值。如果MAX和MIN函數中的列或者表達式是字符型的,則按照首字母從A到Z的順序排序,如果首字母相同,則比較字符串中第二個字母的大小,以此類推。漢字則是按照其漢語拼音的全拼來排序。

 

 

SELECT MAX(salary),MIN(salary)

FROM T_teacher

 

SUM和AVG函數中的表達式隻能是數字類型的值。 

除瞭COUNT(*)之外,其他的幾個函數在計算時都忽略表達式中的空值(NULL行)。 

COUNT函數是用來計算數據表中的總行數,SUM函數是用來計算數據表中某一列的屬性值的總和。 

 

 

SELECT SUM(salary),COUNT(salary),AVG(salary)

FROM T_teacher

 

聚合函數隻能出現在SELECT語句、GROUP BY子句以及HAVING子句中,WHERE子句中不能出現聚合函數。

 

3.使用GROUP BY子句對表中數據進行分組

 

單列分組 

使用GROUP BY子句對數據表中的某一列進行分組時,會對指定分組的列中不同的值都計算出一個統計結果。其語法格式如下: 

GROUP BY列名1 

其中列名1表示需要對該列進行分組操作。 

 

 

SELECT dept,COUNT(profession)

FROM T_teacher

GROUP BY 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子句中經常使用聚合函數對分組後的結果進行篩選。 

 

 

SELECT dept,profession,MAX(salary)

FROM T_teacher

GROUP BY dept,profession

HAVING MAX(salary)>3000

 

註意:GROUP BY下才有HAVING,HAVING用於組;而WHERE是針對SELECT的(針對於表或者視圖),WHERE用於分佈前。 

 

SELECT profession,MAX(salary)

FROM T_teacher

WHERE age>30

GROUP BY profession

HAVING MAX(salary)>3000

 

對分組結果進行排序 

很多時候,對數據表中數據進行分組後,還希望對分組的結果進行排序操作。如果想對使用瞭GROUP BY子句的分組結果進行排序的話,就需要使用ORDER BY子句。 

 

 

SELECT dept,profession,MAX(salary)

FROM T_teacher

GROUP BY dept

ORDER BY MAX(salary) DESC

 

按照GROUP BY後分得的各組中的最高工資給組排序;而如下語句則是按照每組的第一行的工資給組排序。 

 

 

SELECT dept,profession,MAX(salary)

FROM T_teacher

GROUP BY dept

ORDER BY salary DESC

 

GROUP BY子句中處理NULL值 

在使用GROUP BY子句對對指定列進行分組時,有時可能會遇到指定列中含有NULL值的情況。此時,GROUP BY子句會將該列中所有的NULL值歸為一組。 

如果要得到每個分組中的工資的最大值對應的行(而不是分組的第一行),可以使用子查詢等方法,詳細以後討論。 

 

 

select teaName,salary

from (select * from t_teacher order by salary desc) temp

group by dept

order by salary

 

4.使用ROLLUP關鍵字統計數據

 

在實際應用中,有時不僅需要得到分組後的統計結果,還希望對分組的統計結果做進一步的計算,例如通過對教師信息表(T_teacher)中的院校和教師職稱進行分組,得到分組後教師的工資,還希望對每一個院系中的教師的工資做一個階段性的統計,希望得到各個院校中不同職稱的教師的工資的加和(相當於小計),還希望得到所有院校不同職稱教師工資的總和(相當於總計)。這個時候僅僅使用GROUP BY子句是無法做到的,此時就需要使用ROLLUP關鍵字。 

ROLLUP關鍵字使用時需要放到GROUP BY關鍵字的後面。ROLLUP關鍵字在不同的資料庫中的使用方式上稍有不同。 

a.在MySQL和Microsoft SQL Server資料庫中需要使用WITH ROLLUP。其語法格式如下:

 

 

GROUP BY 列名1 WITH 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表示要限制結果集行數。

 

 

SELECT teaID,teaName,dept,profession

FROM T_teacher

ORDER BY teaID

LIMIT 3

— 升序排序後的前3條記錄

LIMIT 3,3

— 升序排序後的第4條到第6條記錄

 

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%的行數,它是可選的。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。