天天看點

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

1.分組查詢的原理圖

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

對上述原始資料,按照DEPARTMENT_ID

(員工id)

分組統計SALARY

(薪水)

平均值

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

上述原理寫成代碼,應該怎麼寫呢?

select 
	department_id,avg(salary)
from 
	test
group by 
	department_id;           

複制

可以清楚地看到,使用

department_id

進行分組後,系統預設将

department_id

相同的号所在的行,配置設定在一起,你有幾個不同的

department_id

,就會分為幾組,每個組中的資料行數,不一定都要相同。

當自動配置設定完成後,會根據你所寫的分組函數,進行

組内運算

也就是說,你使用的是

sum()

函數,就會組内求和;當你使用的是

avg()

函數,就會組内求平均值;當你使用的是

count()

函數,就會進行組内計數;當你使用的是

max()

函數,就會進行組内求最大值;你使用的是

min()

函數,就會進行組内求最小值。

2.group by關鍵字文法詳解

有些小白在學習MySQL的過程中,很多都是在

group by

關鍵字這個地方卡殼。于是我希望自己能夠用

白話圖文

的方式,讓你真正搞明白這個關鍵字的含義。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

group by

是用于

分組查詢

的關鍵字,一般是配合

sum(),avg(),count(),max(),min()

聚合函數使用的。也就是說SQL語句中隻要有

group by

,那麼在select後面的展示字段中一般會有聚合函數(

5個聚合函數

)中的一個或多個函數出現。觀察上圖,有一點你需要記住,你用表中的字段A進行分組後,一般就需要對表中的其它字段,使用聚合函數,這樣意義更大,而不是還對字段A使用聚合函數,沒啥太大意義。

我們再思考下面這個問題!

當SQL語句中使用了

group by

後,在select後面一定有一個字段使用了聚合函數(

5個聚合函數

)。但是除了這個聚合函數,select後面還可以添加其他什麼字段嗎?

答案肯定是可以的!但是該字段有一定的限制,并不是什麼字段都可以。也就是說,當SQL語句中使用了

group by

關鍵字後,select後面除了聚合函數,就隻能是

group by

後面出現的字段。也就是圖中的

字段A

,select後面隻能存在

group by

後面的字段。

3.一個簡單的分組查詢的案例

案例 :

按照部門編号deptno分組,統計每個部門的平均工資。

select 
    deptno,avg(sal) avgs
from 
    emp
group by 
    deptno           

複制

結果如下:

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

4.分組前篩選和分組後篩選

這個知識點就是要帶着大家了解一下,什麼使用該用where篩選?什麼時候該用having篩選?這個知識點對于學習MySQL的小白來說,也是一個棘手的事兒。不用擔心,跟着黃同學學MySQL,沒有學不會的。

1)原始表和結果集的概念

  • 原始表

    指的是資料庫中

    真正存在

    的那個表,使用【select * from 表名】查詢出來的就是原始表資訊。
  • 結果集

    指的是在SQL語句中,添加其它任何一個限制條件,最終展示給我們表,都是結果集。添加不同的限制條件,查詢出來的結果集也是不同的。
  • 原始表

    隻有一個,

    結果集

    卻是各種各樣的。

2)黃同學支大招

  • 隻要是需求中,涉及到聚合函數做條件的情況,一定是分組後的篩選。
  • 能用分組前篩選的,就優先考慮分組前的篩選。(考慮到性能問題)
帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

3)案例講解

原始資料集如下:

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!
① 分組前篩選

習題一:查詢姓名中包含S字元的,每個部門的工資之和。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

習題二:查詢工資大于2000的,不同部門的平均工資。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!
② 分組後篩選

習題一:查詢部門員工個數大于3的部門編号和員工個數。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

習題二:查詢每個部門最高工資大于3000的部門編号和最高工資。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!
③ 分組前篩選和分組後篩選合用

習題:查詢1981年入職的,不同部門間工資的平均值大于2000的部門編号和平均值。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

5.分組查詢(按函數分組)

習題:按員工姓名的長度分組,查詢每一組的員工個數,篩選員工個數>3的有哪些?

select length(ename) len,count(*) counts
from emp
group by len
having counts > 3;           

複制

結果如下:

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

6.分組查詢(按多個字段分組)

習題:查詢每個部門每個工種的員工的平均工資。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

7.group by和order by,一對老搭檔

習題一:查詢每個部門的員工的平均工資,按照平均工資降序。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

習題二:查詢每個部門的員工的平均工資,按照平均工資升序。

帶你學MySQL系列 | 困擾MySQL初學者的分組聚合查詢,我終于講明白了!

8.分組查詢的總結

  • 1)分組函數做條件,肯定是放在

    having

    子句中。
  • 2)能用分組前篩選的,就優先考慮使用分組前篩選。(

    where

    篩選)
  • 3)

    group by

    子句支援單個字段分組,多個字段分組(多個字段之間用逗号隔開沒有順序要求),還支援函數分組(用的較少)。