一 查询格式
select column, group_function(column)
from 表名
[where 筛选条件]
group by 分组列表
[order by 子句]
注意:查询列表比较特殊,要求是分组函数和group by后面的字段,group by 和having后面都可以使用语句的前部分定义的别名,where后面不能使用别名。
二 分组查询的案例
注意:有筛选条件的分组查询分为分组前筛选和分组后筛选两种,分组前筛选是通过原表就可以筛选,分组后筛选是必须依赖分组的结果才能筛选,像这种查询可能猛的一下看不出来怎么写,如下步骤能简化求解:
1. 先写出框架select ... from ... group by ...
2. 观察筛选条件是分组前筛选还是分组后筛选,然后再依次加到查询语句中分组前筛选放到where后面,分组后筛选放到having后面;如果是聚合函数的结果作为筛选条件,一定是分组后筛选;能用分组前筛选的尽量用分组前筛选
1. 简单的分组查询
select job_id,MAX(salary) from employees group by job_id;
select location_id, count(*) from departments group by location_id;
2. 添加分组前进行筛选
select department_id,AVG(salary) from employees where email like '%a%' group by department_id;
select manager_id,MAX(salary) from employees where commission_pct is not null group by manager_id;
3. 添加分组后进行筛选,需要和HAVING配合使用
select department_id,count(*) as countofem from employees group by department_id having count(*)>2;
select job_id,MAX(salary) from employees where commission_pct is not null group by job_id having MAX(salary)>12000;
select manager_id,MIN(salary) from employees where manager_id>102 group by manager_id having MIN(salary)>5000;
#案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数大于5的有那些组
select LENGTH(last_name),count(*) from employees group by LENGTH(last_name) having count(*)>5;
4. 按多个字段分组
#案例:查询每个部门每个工种的员工的平均工资
select department_id,job_id, AVG(salary) as 平均工资 from employees group by department_id, job_id;
5. 添加排序
#案例:查询每个部门每个工种的员工的平均工资,并按照平均工资的高低显示出来
select department_id,job_id, AVG(salary) as 平均工资 from employees where department_id is not null group by department_id, job_id order by AVG(salary);