前面我們介紹了MySQL數據庫中的建表導表的步驟以及基礎的SELECT語句,本篇再基於第一篇文章的數據基礎上我們梳理下聚合和分組。
對錶進行聚合學習重點
- 使用聚合函數對錶中的列進行計算合計值或者平均值等的彙總操作。
- 通常,聚合函數會對NULL以外的對象進行彙總。但是隻有COUNT函數例外,使用COUNT(*)可以查出包含NULL在內的全部數據行數。
- 使用DISTINCT關鍵字刪除重複值。
通過SQL對數據進行某種操作或計算時需要使用某種函數,如:計數count函數,求和sum函數等。
以下是5個最常用的函數:
- count:計算表中的記錄數(行數)
- sum:計算表中數值列中數據的合計值
- avg:計算表中數值列中數據的平均值
- max:求出表中任意列中數據的最大值
- min:求出表中任意列中數據的最小值
用於彙總的函數稱爲聚合函數,所謂聚合,就是將多行彙總爲一行,實際上,所有的聚合函數都是這樣,輸入多行輸出一行。
例如我們將上面的第2題改一改
- 查詢1990年出生的學生人數
select
count(s_id)
from
student
where
year(s_age)='1990';
運行結果如下:(這裏由原來的5行記錄彙總聚合成了一行)
- 查詢"李"姓老師的數量
select
count(t_id) as "李"姓老師的數量
from
teacher
where
t_name like '李%'
group by
t_id;
運行結果如下:(這裏由原來的5行記錄彙總聚合成了一行)
select count(t_id) as ‘"李"姓老師的數量’ from teacher where t_name like ‘李%’ group by t_id;
對錶進行分組學習重點
-
使用GROUP BY子句可以像切蛋糕那樣將表分割。通過使用聚合函數和GROUP BY子句,可以根據某個分組依據將表分割後再進行彙總。
-
聚合鍵中包含NULL時,在結果中會以“不確定”行(空行)的形式表現出來。
-
使用聚合函數和GROUP BY子句時需要注意以下4點。
1.只能寫在SELEC子句之中
2.GROUP BY子句中不能使用SELECT子句中列的別名
3.GROUP BY子句的聚合結果是無序的。
4.WHERE子句中不能使用聚合函數。
如果只使用聚合函數,則是針對表中的所有數據進行彙總處理,如果我們想把表中的數據按某種劃分方式劃分成幾組,再看每組的彙總結果,比如我們想看一下每門課程的學生人數該怎樣去處理呢?那就需要加入GROUP BY子句。
語法6. GROUP BY子句
SELECT <列名>,...
FROM <表名>
GROUP BY <列名>,...;
下面我們來練習一下
- 查詢每門課程被選修的學生數
select
c_id,
count(s_id) as '選修學生數'
from
stu_sco
group by
c_id;
運行結果如下:
可以看出在未使用GROUP BY子句時,結果只有一行,使用GROUP BY子句後,將表中的數據按照c_id進行了切分處理,然後返回每組的聚合結果。
- 查詢同名同姓學生名單,並統計同名人數
select
s_name,
count(s_name)-1 as num
from
student
group by
s_name;
運行結果如下:
這裏我們可以看數據中並沒有重名的人。
這裏我們思考一個問題:
那麼分組和聚合的關係是什麼呢?是有聚合就一定有分組呢?還是有分組就一定有聚合呢?再或者是兩者必須同時出現缺一不可呢?
這裏小編給出的答案是:這裏並沒有什麼絕對的情況。
- 當然一般情況下兩者是同時出現的。(我們既然進行了分組,是想看分組後返回的每組的聚合結果)
- 有聚合沒有分組的情況:例如我們題3中,只有count(*)並沒有group by ,是因爲這裏我們查的是where條件篩選後的全部行的計數,只有一組的情況下,就不需要group by啦。
- 有分組沒有聚合的情況:當按照主鍵進行分組時,select子句中沒有聚合函數代碼也不會報錯,但這樣的分組也基本沒有意義,基本不會這樣去寫,這裏只是舉個小栗子🌰。