按照字段分组,表示此字段相同的数据会被放到一个组中,使用GROUP BY子句将表中的数据分成若干组。
# 完整语法(where和order by语句可以不要)
select
查询列表
from
表
where
筛选条件
group by
分组的字段
order by
排序的字段;
在SELECT 列表中所有未包含在组函数中的列都应该包含在GROUP BY 子句中。

案例一中,select查询列表中的job_id不包含在组函数(聚合函数)中,所以要在group by子句中。
分组查询的特点
- 和分组函数一同查询的字段必须是group by后出现的字段
- 筛选分为两类:分组前筛选和分组后筛选
针对的表 | 位置 | 连接的关键字 | |
分组前筛选 | 原始表 | group by前 | where |
分组后筛选 | group by后的结果集 | group by后 | having |
注意
- 分组函数做筛选不能放在where后面,应该使用在having后面。
- 一般来讲,能用分组前筛选的,尽量使用分组前筛选,提高效率,能使用where的查询条件尽量不要使用having。
案例
查询每个工种的员工平均工资
SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;
查询每个位置的部门个数
SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;
查询邮箱中包含a字符的 每个部门的最高工资
SELECT MAX(salary),department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;
查询有奖金的每个领导手下员工的平均工资
SELECT AVG(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;
查询哪个部门的员工个数>5
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>5;
查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
SELECT job_id,MAX(salary)
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;
查询领导编号>102的每个领导手下的最低工资大于5000的领导编号和最低工资
SELECT manager_id,MIN(salary)
FROM employees
GROUP BY manager_id
HAVING MIN(salary)>5000;
查询每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序
SELECT job_id,MAX(salary) m
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING m>6000
ORDER BY m;
查询每个工种每个部门的最低工资,并按最低工资降序
SELECT MIN(salary),job_id,department_id
FROM employees
GROUP BY department_id,job_id
ORDER BY MIN(salary) DESC;
留言