02-分组查询group by和having的使用

分组查询

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) 分页显示查询到的数据
	……

猜你喜欢

转载自blog.csdn.net/qq_57005976/article/details/135038572