分组查询
MySQL中默认是对整张表的数据进行操作即整张表为一组, 如果想对每一组的数据进行操作,这个时候我们需要使用分组查询
分组函数的执行顺序
: 先根据where条件筛选数据,然后对查询到的数据进行分组,最后也可以采用having
关键字过滤取得正确的数据
group by子句
在一条select语句当中若有group by
关键字,那么在select语句后面只能跟分组函数和参与分组的字段
,其它的一律不能跟否则毫无意义
- 如果跟其他的字段,在MySQL数据库中虽然可以执行但是毫无意义,在Oracle数据库中执行就会报错,因为Oracle的语法比MySQL的语法严格
分组函数的依据可以是一个字段
或多个字段联合成一个字段(使用逗号隔开)
,只要满足分组的依据即一个或多个字段的值都相同时
才算一组
按照工作岗位分组
: 查询每个工作岗位的工资合计,要求显示岗位名称和工资合计
select job, sum(sal) from emp group by job;
按照工作岗位和部门编码分组
: 查询每个工作岗位的每个部门的工资合计
# 部门编号和工作岗位联合起来看成一个字段分组,只要二者都相同时才算一个分组
select job,deptno,sum(sal) from emp group by job,deptno;
计算每个岗位的平均薪资
,要求显示除MANAGER岗位之外平均薪资大于1500的岗位且按照平均薪资降序排列
select
job, avg(sal) as avgsal
from
emp
where
job <> 'MANAGER'
group by
job
having
avg(sal) > 1500
order by
--注意 avgsal 之所以能用的原因 是先执行select后已经为avg(sal) 起了别名 , 所以再执行 order by 的时候当然也可以用
avgsal desc;
where和having子句
分完组后若没有达到要求,可以使用having
关键字对分完组之后的数据进一步过滤
- having不能单独使用, 不能代替where, 必须和group by联合使用
where和having的应用
: 能在where中过滤的数据优先选择在where中过滤,where完成不了的再选择having,having的过滤是专门对分组之后的数据进行过滤的
先分组再筛选(不推荐)
: 找出每个部门最高薪资大于3000的员工,先分组会把那些不符合条件的数据也进行分组会导致sql语句执行效率比较低
select
deptno,max(sal)
from
emp
group by
deptno
having
max(sal) > 3000;
先筛选再分组(推荐)
: 找出每个部门最高薪资大于3000的员工, 先将符合条件的员工找出来然后再分组执行效率高
select
deptno,max(sal)
from
emp
where
sal > 3000
group by
deptno
having的应用
: 查询每个部门的平均薪资,要求显示平均薪资高于2500的
select
deptno,avg(sal)
from
emp
group by
deptno
having
avg(sal) > 2500;
一个完整的 select 语句
select 语句的执行顺序
select --> (5)查询数据
字段
from ---> (1)确定某张表
表名
where --->(2)经过where条件从原始数据筛选出有价值的数据
……
group by --->(3)对这些有价值的数据进行分组
……
having -->(4)分组之后可以使用having继续筛选,having关键字不可以单独出现
……
order by -->(6)对查询到的数据排序输出
……
limit -->(7) 分页显示查询到的数据
……