分组查询:
#进阶5:分组查询
/*
语法:
SELECT 分组函数,列(要求出现在GROUP BY的后面)
FROM 表
【WHERE 筛选条件】
GROUP BY 分组的列表
【ORDER BY 子句】
注意:
查询列表必须特殊,要求是分组函数和GROUP BY后出现的字段
特点:
1.分组查询中的筛选条件
数据源 位置 关键字
分组前筛选 原始表 GROUP BY子句的前面 WHERE
分组后筛选 分组后的结果集 GROUP BY子句的后面 HAVING
2.分组函数做条件肯定是放在HAVING子句中
3.能用分组前筛选的就优先使用分组前筛选
4.GROUP BY子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开,没有顺序要求)
,表达式或函数
5.也可以添加排序(排序放在整个分组查询的最后)
*/
#引入:查询每个部门的平均工资
SELECT
AVG( salary ),
department_id
FROM
employees
GROUP BY
department_id;
#案例1:查询每个工种的最高工资
SELECT
MAX( salary ),
job_id
FROM
employees
GROUP BY
job_id;
#案例2:查询每个位置上的部门个数
SELECT
COUNT( department_id ),
location_id
FROM
departments
GROUP BY
location_id ;
#添加分组前的筛选条件
#案例1:查询邮箱中包含A字符的,每个部门的平均工资
SELECT
AVG( salary ),
department_id,
email
FROM
employees
WHERE
email LIKE '%A%'
GROUP BY
department_id;
#案例2:查询有奖金的每个领导手下员工的最高工资
SELECT
MAX( salary ),
manager_id,
commission_pct
FROM
employees
WHERE
commission_pct IS NOT NULL
GROUP BY
manager_id;
#添加复杂的筛选条件(分组后的筛选)
#案例1:查询哪个部门的员工个数大于2
/*
1.查询每个部门的员工个数
SELECT
COUNT( employee_id ),
department_id
FROM
employees
GROUP BY
department_id;
2.根据1.的结果进行筛选,查询哪个部门的员工数大于2
*/
SELECT
COUNT( employee_id ),
department_id
FROM
employees
GROUP BY
department_id
HAVING
COUNT( employee_id )>2;
#案例2:查询每个工种有奖金的员工的最高工资>12000的工种编号和其最高工资
SELECT
MAX( salary ),
job_id
FROM
employees
WHERE
commission_pct IS NOT NULL
GROUP BY
job_id
HAVING
MAX( salary ) > 12000;
#案例3:查询领导编号>102的每个领导手下的员工的最低工资>5000的领导编号是谁,以及其最低工资
SELECT
MIN( salary ),
manager_id
FROM
employees
WHERE
manager_id > 102
GROUP BY
manager_id
HAVING
MIN( salary ) > 5000;
#按表达式或函数分组
#案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数大于5的有哪些
SELECT
COUNT( job_id ),
last_name
FROM
employees
GROUP BY
LENGTH( last_name )
HAVING
COUNT( job_id ) > 5
ORDER BY
LENGTH( last_name );
#按多个字段分组
#案例:查询每个部门每个工种的员工的平均工资
SELECT
AVG( salary ),
department_id,
job_id
FROM
employees
GROUP BY
department_id,
job_id;
#添加排序
##案例:查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示
SELECT
AVG( salary ),
department_id,
job_id
FROM
employees
WHERE
department_id IS NOT NULL
GROUP BY
job_id,
department_id
HAVING
AVG(salary)>10000
ORDER BY
AVG( salary );
练习题:
#1.查询各个job_id的员工工资的最大值,最小值,平均值,总和,并按JOB_ID升序
SELECT
MAX( salary ),
MIN( salary ),
AVG( salary ),
SUM( salary ),
job_id
FROM
employees
GROUP BY
job_id
ORDER BY
job_id;
#2.查询员工最高工资和最低工资的差距
SELECT
MAX( salary ),
MIN( salary ),
MAX( salary ) - MIN( salary ) AS DIFFERENCE
FROM
employees;
#3.查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内
SELECT
MIN( salary ),
manager_id
FROM
employees
WHERE
manager_id IS NOT NULL
GROUP BY
manager_id
HAVING
MIN( salary ) >= 6000;
#4.查询所有部门的编号,员工数量和工资平均值,并按平均工资降序
SELECT
COUNT( job_id ),
AVG( salary ),
department_id
FROM
employees
GROUP BY
department_id
ORDER BY
AVG( salary ) DESC;
#5.选择具有各个JOB_ID的员工数
SELECT
COUNT( job_id ),
job_id
FROM
employees
WHERE
job_id IS NOT NULL
GROUP BY
job_id ;