1. 语法
SELECT
分组函数,列(要求出现在GROUP BY的后面)
FROM
表名
【WHERE
筛选条件】
GROUP BY
分组的列表
【ORDER BY
子句;】
【】表示可选项。
2. 特点
1)分组查询中筛选条件分为两类:
- 分组前筛选:数据源为原始表,位置在group by子句前面,关键字为WHERE
- 分组后筛选:数据源为分组后的结果集,位置在group by子句后面,关键字为HAVING
2)分组函数做条件肯定放在HAVING子句中
3)能用分组前筛选的优先使用分组前筛选(主要考虑的是效率问题)
3. 示例
(1)查询每个工种(job_id)的最高工资(salary)(表名: JDSC)
SELECT
MAX(salary),
job_id
FROM
JDSC
GROUP BY
job_id;
(2)查询每个位置(location_id)上的部门个数(表名: JDSC)
SELECT
COUNT(*),
location_id
FROM
JDSC
GROUP BY
location_id;
(3)简单筛选条件(分组前)——查询邮箱(email)中包含a字符的,每个部门(department_id)的平均工资(salary)
SELECT
AVG(salary),
department_id
FROM
JDSC
WHERE
email LIKE '%a%'
GROUP BY
department_id;
(4)简单筛选条件(分组前)——查询有奖金(commission_pct)的每个领导(manage_id)手下员工的最高工资(salary)
SELECT
MAX(salary),
manage_id
FROM
JDSC
WHERE
commission_pct IS NOT NULL
GROUP BY
manage_id;
(5)复杂筛选条件(分组后)——查询哪个部门(department_id)的员工个数大于2
SELECT
COUNT(*),
department_id
FROM
JDSC
GROUP BY
department_id
HAVING
COUNT(*)>2;
(6)复杂筛选条件(分组后)——查询每个工种有奖金的员工的最高工资大于12000的工种编号和最高工资
SELECT
MAX(salary),
job_id
FROM
JDSC
WHERE
commission_pct IS NOT NULL
GROUP BY
job_id
HAVING
MAX(salary)>12000;
(7)复杂筛选条件(分组后)——查询领导编号大于102的每个领导手下的最低工资大于5000的领导编号,以及最低工资
SELECT
MIN(salary),
manage_id
FROM
JDSC
WHERE
manage>102
GROUP BY
manage_id
HAVING
MIN(salary)>5000;