06_MySQL DQL_分组查询
# 分组查询
/*
语法:
select 分组函数,列(group by中出现的字段)
from 表
【where 筛选条件】
group by 分组的列表(单个字段,多个字段,函数,表达式)
【having 分组后筛选】
【order by 子句】
执行顺序:
表 -> 分组前筛选 -> group by分小组 -> 分组统计 -> 分组后筛选 -> 排序
注意:
查询列表比较特殊:分组函数(统计值,一组一值), group by后出现的字段
特点:
1、分组查询中的筛选条件分为两类
分组前的筛选 原始表 筛选条件位于group by子句之前 where关键字
分组后的筛选 分组后的结果 筛选条件位于group by子句之后 having关键字
分组函数做筛选条件,肯定是在having子句,既分组后的筛选
*/
# 引入:查询每个部门的平均工资
# 本质:分组->小表
SELECT AVG(salary),department_id # 每组保留一个department_id
FROM employees
GROUP BY department_id;
# 案例1:查询每个工种的最高工资【简单分组查询】
SELECT MAX(salary),job_id
FROM employees
GROUP BY job_id;
# 案例2:查询每个工作地的部门个数
SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;
# 添加筛选条件
# 案例1: 查询邮箱中包含a字符的,每个部门的平均工资
SELECT AVG(salary), department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;
# 案例2: 有奖金的,每个领导手下员工的最高工资
SELECT MAX(salary), manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;
# 添加分组后的筛选条件【having子句】
# 案例1:哪个部门的员工个数>2
#1.查询出每个部门的员工个数,中间结果
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id;
#2.根据1的结果,筛选出员工数大于2的最终结果
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;
# 案例2:查询每个工种有奖金的员工的最高工资>12000的工种编号和工资
#1)查询每个工种中有奖金的员工的最高工资【分组前的筛选】
SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id;
#2) 在1的基础上,过滤出最高工资》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的领导编号,以及最低工资
# 1. 查询领导编号>102的每个领导下的最低工资【分组前筛选】
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id;
# 2. 在1的基础上,筛选出最低工资》5000的最低工资,领导编号【分组后筛选】
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000;
# 按表达式/函数,分组查询
# 案例1:按员工姓名长度进行分组,查询每组员工的个数,筛选出员工个数>5
#1 按员工姓名长度进行分组,查询每组员工个数
SELECT COUNT(*), LENGTH(last_name)
FROM employees
GROUP BY LENGTH(last_name);
#2 分组后增加筛选条件
SELECT COUNT(*), LENGTH(last_name)
FROM employees
GROUP BY LENGTH(last_name)
HAVING COUNT(*)>5;
# 按多个字段分组查询
# 案例1:查询每个部门每个工种的员工平均工资
SELECT AVG(salary),job_id,department_id
FROM employees
GROUP BY department_id,job_id; # 先按部门分组,再按工种分组
# 添加排序
# 案例1:查询每个部门每个工种的员工平均工资,从高到低显示平均工资高于1万的结果
SELECT AVG(salary),department_id,job_id
FROM employees
WHERE department_id IS NOT NULL
GROUP BY department_id,job_id
HAVING AVG(salary)>10000
ORDER BY AVG(salary) DESC; # 对最终结果的排序