數(shù)據(jù)的排序與分組語句
使用SQL語句執(zhí)行查詢操作時,我們可能發(fā)現(xiàn)查詢出的數(shù)據(jù)結果的排序是無序的。為了更好的觀察數(shù)據(jù)表中的查詢結果,開發(fā)人員或者用戶經(jīng)常要對查詢的數(shù)據(jù)進行排序操作,這就需要使用ORDER BY子句。在數(shù)據(jù)庫的實際應用中,有時需要對查詢的數(shù)據(jù)進行統(tǒng)計和分組操作,這就需要了解SQL語句的聚合函數(shù)和GROUP BY子句的使用。有些時候開發(fā)人員或者用戶還希望對分組后的結果做進一步的統(tǒng)計,在SQL語句中提供了ROLLUP這樣一個關鍵字用來對數(shù)據(jù)進行統(tǒng)計。最后還將介紹主要數(shù)據(jù)庫中如何限制結果集的行數(shù)。
1.使用ORDER BY子句對數(shù)據(jù)記錄進行排序
指定表中的一列進行排序
通過ORDER BY 子句可以對查詢結果中指定的列進行升序或者是降序操作,這取決于ORDER BY子句后的關鍵字,如果ORDER BY子句后面的關鍵字是ASC,則對查詢的結果執(zhí)行升序操作;如果ORDER BY子句后面的關鍵字是DESC,則對查詢的結果執(zhí)行降序操作。其語法規(guī)則如下
ORDER BY 列名1 [ASC|DESC]
其中列名1表示需要對該列進行排序操作。關鍵字ASC和DESC是可選的。如果ORDER BY 子句后面不寫ASC或者是DESC,則默認執(zhí)行的是升序操作。
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語句中出現(xiàn)的選擇列進行排序操作。
SELECT teaID,teaName,dept,profession
FROM T_teacher
WHERE dept ='計算機系'
ORDER BY salary
指定表中的多列進行排序
ORDER BY子句除了可以指定單列進行排序操作,也可以指定數(shù)據(jù)表中的多個列進行排序操作。如果要指定數(shù)據(jù)表中的多個列進行排序操作,則指定排序的列與列之間需要用逗號隔開。其語法規(guī)則如下:
ORDER BY 列名1[ASC|DESC],列名2 [ASC|DESC]
其中列名1和列名2表示需要對指定的數(shù)據(jù)列進行排序操作。列名1和列名2之間用逗號進行分割。關鍵字ASC和DESC是可選的。如果ORDER BY 子句后面不寫ASC或者DESC,則默認執(zhí)行的是升序操作。首先,根據(jù)ORDER BY中指定的第一列進行排序;然后,再根據(jù)ORDER BY子句中指定的第二列的升序或者降序方式進行排序。
SELECT teaID,teaName,dept,profession,salary
FROM T_teacher
ORDER BY salary DESC,dept ASC
2.常用的聚合函數(shù)
聚合函數(shù)也被稱為分組函數(shù)或者統(tǒng)計函數(shù),主要用于對得到的一組數(shù)據(jù)進行統(tǒng)計計算,例如求和、求平均值等,常用的聚合函數(shù)包括COUNT、MAX、MIN、SUM和AVG五個。
COUNT、SUM和AVG函數(shù)中可以使用DISTINCT關鍵字去除指定列中的重復項。使用DISTINCT關鍵字后只是對不同行的值進行統(tǒng)計。
MAX和MIN函數(shù)中的列或者表達式可以是數(shù)字型、字符型或者是日期類型的值。如果MAX和MIN函數(shù)中的列或者表達式是字符型的,則按照首字母從A到Z的順序排序,如果首字母相同,則比較字符串中第二個字母的大小,以此類推。漢字則是按照其漢語拼音的全拼來排序。
SELECT MAX(salary),MIN(salary)
FROM T_teacher
SUM和AVG函數(shù)中的表達式只能是數(shù)字類型的值。
除了COUNT(*)之外,其他的幾個函數(shù)在計算時都忽略表達式中的空值(NULL行)。
COUNT函數(shù)是用來計算數(shù)據(jù)表中的總行數(shù),SUM函數(shù)是用來計算數(shù)據(jù)表中某一列的屬性值的總和。
SELECT SUM(salary),COUNT(salary),AVG(salary)
FROM T_teacher
聚合函數(shù)只能出現(xiàn)在SELECT語句、GROUP BY子句以及HAVING子句中,WHERE子句中不能出現(xiàn)聚合函數(shù)。
3.使用GROUP BY子句對表中數(shù)據(jù)進行分組
單列分組
使用GROUP BY子句對數(shù)據(jù)表中的某一列進行分組時,會對指定分組的列中不同的值都計算出一個統(tǒng)計結果。其語法格式如下:
GROUP BY列名1
其中列名1表示需要對該列進行分組操作。
SELECT dept,COUNT(profession)
FROM T_teacher
GROUP BY dept
Select同時包含數(shù)據(jù)列和聚合函數(shù)時,必須使用Group By。
多列分組
使用GROUP BY子句對數(shù)據(jù)表中的多個列進行分組時,會對指定分組的多個列中不同的值都計算出一個統(tǒng)計結果。其語法格式如下:
GROUP BY列名1,列名2…
其中列名1和列名2表示需要對指定列進行分組操作。列名1和列名2之間用逗號進行分割。
使用HAVING子句子限制分組后的查詢結果
如果想要對分組后的結果限制查詢條件,就需要使用HAVING子句。由于HAVING子句是用來限制分組后的查詢結果,所以該子句需要放到GROUP BY子句的后面使用。其語法格式如下:
GROUP BY列名1 HAVING 條件表達式
其中列名1表示需要對該列進行分組操作。HAVING子句后的條件表達式是用來篩選分組后的結果。在HAVING子句中經(jīng)常使用聚合函數(shù)對分組后的結果進行篩選。
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
對分組結果進行排序
很多時候,對數(shù)據(jù)表中數(shù)據(jù)進行分組后,還希望對分組的結果進行排序操作。如果想對使用了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ǒng)計數(shù)據(jù)
在實際應用中,有時不僅需要得到分組后的統(tǒng)計結果,還希望對分組的統(tǒng)計結果做進一步的計算,例如通過對教師信息表(T_teacher)中的院校和教師職稱進行分組,得到分組后教師的工資,還希望對每一個院系中的教師的工資做一個階段性的統(tǒng)計,希望得到各個院校中不同職稱的教師的工資的加和(相當于小計),還希望得到所有院校不同職稱教師工資的總和(相當于總計)。這個時候僅僅使用GROUP BY子句是無法做到的,此時就需要使用ROLLUP關鍵字。
ROLLUP關鍵字使用時需要放到GROUP BY關鍵字的后面。ROLLUP關鍵字在不同的數(shù)據(jù)庫中的使用方式上稍有不同。
a.在MySQL和Microsoft SQL Server數(shù)據(jù)庫中需要使用WITH ROLLUP。其語法格式如下:
GROUP BY 列名1 WITH ROLLUP
其中列名1表示要對該列進行分組,WITH ROLLUP關鍵字表示要對分組的結果進行統(tǒng)計。當然也可以對多個列進行分組,并統(tǒng)計分組后的結果。其語法格式如下:
GROUP BY 列名1 ,列名2 WITH ROLLUP
b.在Oracle數(shù)據(jù)庫中,ROLLUP關鍵字需要緊跟在GROUP BY關鍵字的后面,然后再寫需要分組的字段。其語法格式如下:
GROUP BY ROLLUP (列名1,列名2…)
5.限制結果集行數(shù)
有些時候,開發(fā)人員或者用戶并不希望將查詢結果的數(shù)據(jù)列中的數(shù)據(jù)全部顯示出來,而是只希望顯示其中的幾行,尤其是在需要分頁的操作中。例如,一個數(shù)據(jù)表最后查詢出了100條記錄,而開發(fā)人員或者用戶只關心其中前10條記錄的值,這就需要對查詢結果中的數(shù)據(jù)記錄的行數(shù)進行限制。在不同的數(shù)據(jù)庫中限制結果集行數(shù)的方法也不盡相同。
a.在MySQL數(shù)據(jù)庫中限制結果集行數(shù)可以使用LIMIT關鍵字,它可以用來限制查詢出來的數(shù)據(jù)結果的個數(shù)。通過使用LIMIT關鍵字可以讓開發(fā)人員或者用戶得到其中想要的部分的結果。如果要使用LIMIT限制結果集行數(shù),可以使用下面的語法格式。
LIMIT n
其中LIMIT是關鍵字,數(shù)字n表示要限制結果集行數(shù)。
SELECT teaID,teaName,dept,profession
FROM T_teacher
ORDER BY teaID
LIMIT 3
-- 升序排序后的前3條記錄
LIMIT 3,3
-- 升序排序后的第4條到第6條記錄
b.Oracle數(shù)據(jù)庫中不支持類似于 MySQL 中的 LIMIT關鍵字來限制結果集行數(shù),但是在 Oracle數(shù)據(jù)庫中可以使用ROWNUM關鍵字限制結果集的行數(shù)。其語法格式如下:
WHERE ROWNUM 其中ROWNUM關鍵字表示對符合條件結果的序列號,它的起始值總是從1開始的。數(shù)字n表示要限制的結果集的行數(shù)。當然,這里的比較運算符除了可以使用(<)小于以外,還可以使用(<=)小于等于。 c.MySQL數(shù)據(jù)庫和Oracle數(shù)據(jù)庫中使用LIMIT關鍵字和ROWNUM的方法限制結果集行數(shù),在Microsoft SQL Server數(shù)據(jù)庫中需要使用TOP關鍵字。其語法格式如下: SELECT TOP n [PRECENT] 列名1,列名2 … FROM 表名 … 其中,TOP是表示限制結果集行數(shù)的關鍵字;數(shù)字n表示限制結果集行數(shù);PRECENT關鍵字表示返回查詢的結果集中前n%的行數(shù),它是可選的。
聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com