25 SQL Group By & Having
1. 定義
解釋:
Group By
用於資料分組,一般與聚合函式一起使用,對分組後的資料進行聚合操作。由於 Where 無法與聚合函式一起搭配使用,因此 SQL 增加Having
指令。
2. 前言
本小節,我們將一起學習Group By
和Having
。
SQL 不僅提供資料操作功能相關的指令,而且也提供了一些指令進行資料統計和分析。如,Group By 提供了分組功能對資料分門別類,Having 可以與聚合函式搭配用於篩選資料。
本小節測試資料如下,請先在資料庫中執行:
DROP TABLE IF EXISTS imooc_user;
CREATE TABLE imooc_user
(
id int PRIMARY KEY,
username varchar(20),
age int,
score int
);
INSERT INTO imooc_user(id,username,age,score)
VALUES (1,'peter', 18, 100),(2,'pedro', 24, 500),
(3,'jerry', 24, 500),(4,'mike', 18, 100),(5,'tom', 20, 1000);
提示: 如果你還不熟悉聚合函式,請先閱讀聚合函式小節。
3. Group By
Group By 會根據 By 後面的資料欄位來分組,並且根據給定的聚合函式來分組進行聚合操作。
使用語法如下:
SELECT [agg] FROM [table_name] GROUP BY [col];
其中agg
表示聚合函式,table_name
表示資料表名稱,col
表示欄位名稱。
3.1 例1 單欄位Group By
請書寫 SQL 語句,將imooc_user
表中的使用者通過age
進行分組,並返回每個分組的使用者數。
分析:
題幹中明確指出根據 age 進行分組,因此 Group By 應該後接 age,統計每個分組的使用者數使用聚合函式 Count。
語句:
整理可得語句如下:
SELECT age, COUNT(*) FROM imooc_user GROUP BY age;
結果如下:
+-----+----------+
| age | COUNT(*) |
+-----+----------+
| 18 | 2 |
| 24 | 2 |
| 20 | 1 |
+-----+----------+
提示:
COUNT(*)
在資料庫層面有專門的優化,其效能跟COUNT(1)
大致相同。
3.2 例2 多欄位 Group By
Group By 不僅支援單欄位分組,同時也支援多欄位分組。
請書寫 SQL 語句,使用 age 和 score 欄位對imooc_user
表中的使用者進行分組,並返回每個分組的使用者數。
分析:
題幹中明確指出根據 age 和 score 進行分組,因此 Group By 應該後接 age,score,統計每個分組的使用者數使用聚合函式 Count。
語句:
整理可得語句如下:
SELECT age, score, COUNT(*) FROM imooc_user GROUP BY age, score;
結果如下:
+-----+-------+----------+
| age | score | COUNT(*) |
+-----+-------+----------+
| 18 | 100 | 2 |
| 24 | 500 | 2 |
| 20 | 1000 | 1 |
+-----+-------+----------+
4. Having
Having 不能單獨出現,須於聚合函式搭配使用,且常與 Group By 一起出現。Having 本身並無其他含義,它的主要功能是替代 Where。
使用語法如下:
SELECT [agg] FROM [table_name] GROUP BY [col] HAVING [condition];
其中agg
表示聚合函式,table_name
表示資料表名稱,col
表示欄位名稱,condition
表示過濾條件。
4.1 例3 使用 Having
請書寫 SQL 語句,將imooc_user
表中的使用者通過 age 進行分組,並返回每個分組的使用者數,且每個分組的使用者數必須大於1
。
分析:
題幹中明確指出根據 age 進行分組,因此 Group By 應該後接 age,統計每個分組的使用者數使用聚合函式 Count,且使用 Having 過濾。
語句:
整理可得語句如下:
SELECT age, COUNT(*) FROM imooc_user GROUP BY age HAVING COUNT(*) > 1;
結果如下:
+-----+----------+
| age | COUNT(*) |
+-----+----------+
| 18 | 2 |
| 24 | 2 |
+-----+----------+
5. 小結
- Group By 和 Having 常被用於資料分析和統計,是視覺化和報表的利器。
- Having 侷限於聚合函式,它無法使用在其它場景下。