2.分組
學完了基本的匯總函數溺健,接下來我們來學習如何對數據進行分組。在SQL中我們用group by語句來對數據進行分組:
GROUP BY 語句用于結合聚合函數,根據一個或多個列對結果集進行分組亩进,語法如下:
SELECT column_nameFROM table_nameGROUP BY column_name;
栗子:在“student”表中按性別進行分組并計算人數
SELECT 性別,COUNT(姓名) AS 學生人數FROM studentGROUP BY `性別`;
進一步搀军,我們對出生日期大于1990-01-01的學生按性別分組并計算人數
SELECT 性別,COUNT(姓名) AS 學生人數 -- 運行順序4FROM student -- 1WHERE 出生日期>'1990-01-01' -- 2GROUP BY 性別; -- 3
注意:SQL的運行順序膨俐。
面試題:
查詢各科成績最高和最低的分
SELECT 課程號,MAX(成績),MIN(成績)FROM scoreGROUP BY 課程號;
查詢每門課程被選修的學生人數
SELECT 課程號,COUNT(學號) as 學生人數
FROM score
GROUP BY 課程號;
查詢男生、女生人數(見實例1)
3.對分組結果指定條件
GROUP BY主要作用是用來進行分組聚合罩句,也有時候會用來進行排重焚刺,與DISTINCT關鍵字作用類似。此外還常與HAVING關鍵字一起使用门烂,用來對分完組后的數據進一步的篩選乳愉。
在 SELECT 查詢中,HAVING 子句必須緊隨 GROUP BY 子句屯远,并出現在 ORDER BY 子句(如果有的話蔓姚,我們在后面會講到)之前。帶有 HAVING 子句的 SELECT 語句的語法如下所示:
SELECT column1,column2 --查詢結果
FROM table1,table2 -- 從哪張表中查找數據
WHERE [conditions] -- 查詢條件
GROUP BY column1,column2 -- 分組
HAVING [conditions] -- 對分組結果指定條件
栗子:按性別分組慨丐,篩選出學生人數大于1的學生并計數
SELECT 性別,COUNT(姓名) as 學生人數
FROM student
GROUP BY 性別
HAVING COUNT(姓名)>1;
面試題:
查詢平均成績大于60分學生的學號和平均成績
SELECT 學號,AVG(成績) as 平均成績
FROM score
GROUP BY 學號
HAVING 平均成績>60;
查詢至少選修兩門課程的學生學號
SELECT 學號,COUNT(課程號)as 選修課程數
FROM score
GROUP BY 學號
HAVING 選修課程數>=2;
查詢同名同姓學生名單并統(tǒng)計同名人數
SELECT 姓名,COUNT( 姓名)as 學生人數
FROM student
GROUP BY 姓名
HAVING 學生人數>=2;
4.用SQL解決業(yè)務問題
前面學了這么多坡脐,我們是不是該學以致用,用SQL來解決業(yè)務問題了呢房揭?那么如何用SQL解決業(yè)務問題呢备闲?
把業(yè)務問題解讀成通俗易懂的大白話
寫出分析思路(按步驟分解)
寫出對應的SQL子句
下面我們通過一個實際的例子來看一下晌端,如何使用這個思路來解決問題:
假設老板現在要求你計算各科的平均成績,你就可以按上面步驟浅役,先在草稿紙上寫出問題對應的分析思路斩松,第一步要做什么,第二步要做什么……:
老板要求的關鍵詞:各科觉既、平均成績
從哪張表——>score
各科——>每門課——>按課程號分組惧盹;
平均成績——>對成績求平均值
查詢結果:課程號,平均成績
OK瞪讼!下面我們按照上面的分析思路結合SQL子句的運行順序來寫出對應的SQL子句
SELECT 課程號 ,AVG(成績 ) as 平均成績
FROM score
GROUP BY 課程號;
接下來钧椰,老板讓你進一步篩選出平均成績大于等于80分的:
關鍵詞:篩選、平均成績——>對分組結果指定條件>=80符欠,
SELECT 課程號 ,AVG(成績 ) as 平均成績
FROM score
GROUP BY 課程號
HAVING 平均成績>=80;
這樣你就輕松完成了
面試題:計算各科的平均成績并且平均成績大于等于80分的嫡霞。把上面講的自己操作一遍吧
5.對查詢結果排序
在處理數據時我們經常需要對數據進行排序,在SQL中希柿,我們用order by 語句完成這一操作诊沪。
ORDER BY 關鍵字用于對結果集進行排序。
ORDER BY就是對需要排序的列按升序(ASC)或降序(DESC)排列后顯示數據曾撤,與Excel的排序類似端姚。
ORDER BY 關鍵字默認情況下按升序(ASC)排序記錄,默認排序可以不寫ASC挤悉。
降序的情況下必須寫DESC渐裸,常與TOP關鍵字一起使用。
照例装悲,我們先上語法:
SELECT column1, column2, ... FROM table_nameORDER BY column1, column2, ... ASC|DESC;
此時昏鹃,SQL語句的運行順序為:
(5)SELECT? <select list>
(1)FROM [left_table]
(3)WHERE <where_condition>
(2)GROUP BY <group_by_list>
(4)HAVING <having_condition>
(6)ORDER BY <order_by_list> -- order by 子句在select子句之后運行,因為是對查詢結果進行排序
栗子:例如上面的題诀诊,如改為求出各科的平均成績洞渤,并按降序排列,則就需要加上order by 語句
SELECT 課程號 ,AVG(成績 ) as 平均成績
FROM score
GROUP BY 課程號
ORDER BY 平均成績 DESC;
那如果我們要指定多個排序列名呢
栗子:按成績升序属瓣,課程號降序對score表中的數據進行重新排列
SELECT *
FROM score
ORDER BY 成績 ASC,
課程號 DESC;
/*多個排序列名您宪,按照order by子句中的列名從左到右進行排序的,先排第一個列奠涌,如果第一個列
值相同宪巨,則在此基礎上按第二個列的值進行排序*/
現在新的疑問來了,如果要排序的列里面有空值呢溜畅?如何對空值(null)進行排序捏卓?
我們來看一顆栗子:
對教師表的教師姓名進行排序
SELECT *
FROM teacher
ORDER BY 教師姓名;
可以看出空值是排在最前面的,也就是說如果我們想看一列里面有多少個空值,這樣一排序怠晴,其實就可以知道了遥金。
也許你可能還會問上面排序“教師姓名”這一列里 孟扎扎 為什么排在 馬化騰 的前面呢?在不指定排序規(guī)則的話蒜田,是默認按“升序”排列的稿械。孟(meng)和馬(ma),a 在 e 的前面冲粤,所以 馬化騰 應該排在 孟扎扎 的前面吧美莫?
其實如果數據庫的字符集編碼是utf-8,漢字排序并不是按照字母順序的梯捕;如果數據庫的字符集編碼是gbk厢呵,漢字排序是按照字母順序的。
這里在告訴大家一個小tip:如果一個數據有幾萬條甚至十幾萬條傀顾,我們?yōu)榱颂岣咝式竺幌敕祷仄渲幸徊糠謹祿藭r我們可以使用limit語句短曾。
栗子:
SELECT *
FROM score
LIMIT 2;
這樣就只返回表中的前兩條數據啦
因為limit語句也是對查詢結果進行處理寒砖,所以limit子句也是在select子句之后運行的哦!
面試題:
查詢不及格的課程并按課程號從大到小排列
SELECT 課程號,成績
FROM score
WHERE 成績<60
ORDER BY 課程號 DESC;
查詢每門課程的平均成績嫉拐,結果按平均成績升序排列哩都,平均成績相同時,按課程號降序排列
SELECT 課程號,avg(成績) as 平均成績 -- 查詢結果 [課程號,平均成績:匯總函數avg(成績)]
FROM score -- 從哪張表中查找數據 [成績表score]
GROUP BY 課程號 -- 分組 [每門課程:按課程號分組]
ORDER BY 平均成績 ASC,
課程號 DESC; -- 對查詢結果排序
檢索課程號為“0003”且分數小于90的學生學號椭岩,結果按按分數降序排列
SELECT 課程號,成績
FROM score
WHERE 課程號='0003' and 成績<90
ORDER BY 成績 DESC;
統(tǒng)計每門課程的學生選修人數(超過2人的課程才統(tǒng)計)茅逮,要求輸出課程號和選修人數璃赡,查詢結果按人數降序排序判哥,若人數相同,按課程號升序排序
SELECT 課程號,COUNT(學號) as 選修人數
FROM score
GROUP BY 課程號
HAVING 選修人數>2
ORDER BY 選修人數 DESC,
課程號 ASC;
查詢1門及以上不及格課程的同學的學號及不及格課程的平均成績
select 學號, avg(成績) as 平均成績,count(課程號) as 不及格課程數
from score
where 成績 <60
group by 學號
having count(課程號)>=1;
6.如何看懂報錯信息
學了這么多碉考,做了這么多聯系塌计,是不是經常在運行時出現報錯信息呢?你看懂了嗎侯谁?現在我們就一起來學習如何看懂報錯信息锌仅。
[err] 是指錯誤,表示當前運行的sql語句有錯誤墙贱。
To use near '_______________' atline 4热芹,下劃線處則代表語句出錯的具體位置。
舉顆栗子:
SELECT 課程號,avg(成績) as 平均成績
FROM score
GROUP BY 課程號
ORDER BY 平均成績 ASC
課程號 desc;
那我們就來看一看第5行“課程號 desc;”有什么錯誤惨撇,一檢查“平均成績 ASC”后面少了個逗號伊脓,填上去就解決啦。
其實一般出現報錯魁衙,第一檢查標點符號报腔,第二檢查子句運行順序株搔,第三檢查是否輸入錯誤的列名等等,還有例如where子句中不能使用匯總函數等等纯蛾,總之不要著急纤房,按照報錯提示定位去找就可以了。
還有一些常見問題:在求最大值時翻诉,為什么查詢出來的最大值與實際的最大值不符炮姨?
這是因為這一列數字看起來是數字,但在設置的時候把這一列的數據類型設置成字符串了米丘,排序或者計算時是按字符串類型來計算的剑令,而非數字類型。這兩者的計算規(guī)則是不一樣的拄查,所以實際操作中一定要記得設置好數據類型哦吁津。或者發(fā)現類似問題堕扶,檢查一下是不是數據類型設置成字符串的碍脏,如果是就趕快改過來吧。
好啦稍算,今天所有的內容就到這里啦典尾,雖然寫的很累,但是很開心糊探!接下來我們依然來到我們的SQLZOO钾埂,完成我們的鞏固聯系: