在本教程中,您将学习如何使用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
子句将行汇总到分组中,并将聚合函数应用于每个分组。