在本教學中,您將學習如何使用SQL GROUP BY
子句根據一列或多列對行進行分組。
1. SQL GROUP BY子句簡介
分組是使用資料庫時必須處理的最重要任務之一。 要將行分組,請使用GROUP BY
子句。
GROUP BY
子句是SELECT
語句的可選子句,它根據指定列中的匹配值將行組合成組,每組返回一行。
經常將GROUP BY
與MIN,MAX,AVG,SUM或COUNT等聚合函數結合使用,以計算為每個分組提供資訊的度量。
以下是GROUP BY
子句的語法。
SELECT
column1,
column2,
AGGREGATE_FUNCTION (column3)
FROM
table1
GROUP BY
column1,
column2;
在SELECT
子句中包含聚合函數不是強制性的。 但是,如果使用聚合函數,它將計算每個組的匯總值。
如果要在分組之前過濾行,請添加WHERE
子句。 但是要過濾組,請使用HAVING
子句。
需要強調的是,在對行進行分組之前應用WHERE
子句,而在對行進行分組之後應用HAVING
子句。 換句話說,WHERE
子句應用於行,而HAVING
子句應用於分組。
要對組進行排序,請在GROUP BY
子句後添加ORDER BY
子句。
GROUP BY
子句中出現的列稱為分組列。 如果分組列包含NULL
值,則所有NULL
值都匯總到一個分組中,因為GROUP BY
子句認為NULL
值相等。
2. SQL GROUP BY示例
我們將使用示例資料庫中的employees
和departments
表來演示GROUP BY
子句的工作方式。
要查找每個部門的員工數量,請按department_id
列對員工進行分組,並將COUNT
函數應用於每個組,如下所示:
SELECT
department_id,
COUNT(employee_id) headcount
FROM
employees
GROUP BY
department_id;
執行上面查詢語句,得到以下結果:
2.1. SQL GROUP BY帶有INNER JOIN示例
要獲取部門名稱,請使用departments
表將employees
表連接,如下所示:
SELECT
e.department_id,
department_name,
COUNT(employee_id) headcount
FROM
employees e
INNER JOIN departments d ON d.department_id = e.department_id
GROUP BY
e.department_id;
執行上面查詢語句,得到以下結果:
2.2. SQL GROUP BY帶有ORDER BY示例
要按人數排序部門,請添加ORDER BY
子句作為以下語句:
SELECT
e.department_id,
department_name,
COUNT(employee_id) headcount
FROM
employees e
INNER JOIN
departments d ON d.department_id = e.department_id
GROUP BY e.department_id
ORDER BY headcount DESC;
執行上面查詢語句,得到以下結果:
注意,可以在ORDER BY
子句中使用headcount
別名或COUNT(employee_id)
。
2.3. SQL GROUP BY有HAVING示例
要查找人數大於5
的部門,請使用HAVING
子句,如下查詢語句:
SELECT
e.department_id,
department_name,
COUNT(employee_id) headcount
FROM
employees e
INNER JOIN
departments d ON d.department_id = e.department_id
GROUP BY e.department_id
HAVING headcount > 5
ORDER BY headcount DESC;
執行上面查詢語句,得到以下結果:
+---------------+-----------------+-----------+
| department_id | department_name | headcount |
+---------------+-----------------+-----------+
| 5 | 運輸 | 7 |
| 3 | 採購 | 6 |
| 10 | 財務 | 6 |
| 8 | 銷售 | 6 |
+---------------+-----------------+-----------+
4 rows in set
2.4. SQL GROUP BY與MIN,MAX和AVG示例
以下查詢返回每個部門中員工的最低,最高和平均工資。
SELECT
e.department_id,
department_name,
MIN(salary) min_salary,
MAX(salary) max_salary,
ROUND(AVG(salary), 2) average_salary
FROM
employees e
INNER JOIN
departments d ON d.department_id = e.department_id
GROUP BY e.department_id;
執行上面示例代碼,得到以下結果:
2.5. SQL GROUP BY帶有SUM函數示例
要獲得每個部門的總薪水,請將SUM
函數應用於salary
列,並通過department_id
列分組員工,如下所示:
SELECT
e.department_id,
department_name,
SUM(salary) total_salary
FROM
employees e
INNER JOIN
departments d ON d.department_id = e.department_id
GROUP BY e.department_id;
執行上面查詢語句,得到以下結果:
+---------------+-----------------+--------------+
| department_id | department_name | total_salary |
+---------------+-----------------+--------------+
| 1 | 管理 | 4400.00 |
| 2 | 市場行銷 | 19000.00 |
| 3 | 採購 | 24900.00 |
| 4 | 人力資源 | 6500.00 |
| 5 | 運輸 | 41200.00 |
| 6 | IT | 28800.00 |
| 7 | 公共關係 | 10000.00 |
| 8 | 銷售 | 57700.00 |
| 9 | 行政人員 | 58000.00 |
| 10 | 財務 | 51600.00 |
| 11 | 會計 | 20300.00 |
+---------------+-----------------+--------------+
11 rows in set
2.6. SQL GROUP BY多列
到目前為止,您已經看到將所有員工分組為一列。 例如,以下子句 -
GROUP BY department_id
將所有具有相同值的行放在一個組的department_id
列中。如何按department_id
和job_id
列中的值對員工進行分組?
GROUP BY department_id, job_id
此子句將在一個組的department_id
和job_id
列中為所有具有相同值的員工進行分組。
以下語句將同一組中department_id
和job_id
列中具有相同值的行分組,然後返回每個組的行。
SELECT
e.department_id,
department_name,
e.job_id,
job_title,
COUNT(employee_id)
FROM
employees e
INNER JOIN
departments d ON d.department_id = e.department_id
INNER JOIN
jobs j ON j.job_id = e.job_id
GROUP BY e.department_id , e.job_id;
執行上面示例代碼,得到以下結果:
第2
,3
和5
部門不止一個。
這是因為這些部門的員工有不同的工作。 例如,在運輸部門,有2
名員工在運輸業務員工作,1
名員工在庫存員工作,4
名員工在庫存管理員工作。
2.7. SQL GROUP BY和DISTINCT
如果使用GROUP BY
子句而不使用聚合函數,則GROUP BY
子句的行為類似於DISTINCT
運算符。
以下內容獲取員工的電話號碼,並按電話號碼分組。
SELECT
phone_number
FROM
employees
GROUP BY
phone_number;
注意,電話號碼已排序。
以下語句還檢索電話號碼,但不使用GROUP BY
子句,而是使用DISTINCT
運算符。
ELECT DISTINCT
phone_number
FROM
employees;
結果集是相同的,只是DISTINCT
運算符返回的結果集沒有排序。
在本教學中,我們向您展示了如何使用GROUP BY
子句將行匯總到分組中,並將聚合函數應用於每個分組。