having子句要和group by子句联合起来才能使用,不能单独去使用,接下来咱们看一下为什么要引入having子句语法呢?引入having子句也是出于无奈,因为有些条件查询,用group by子句并不能满足要求,比如说查询部门平均底薪超过2000元的部门编号。按照正常的逻辑,这个sql语句应该写成下面这个样子
sql
select deptno from t_emp
where avg(sal)>=2000
group by deptno
看似这个sql语句在语法上没有什么问题,但是在执行的时候,它一定会报错,语法是有错误的。这又是怎么回事呢?因为where子句,它的优先级是优于group by执行的,所以说这样是有语法错误的,这个时候就要引入having子句了
1. HAVING子句
having子句不能独立存在,它必须要依赖group by子句,所以它的这个执行顺序是group by子句执行完事之后,就立即轮到它来执行了。我们引入了 HAVING 子句,就可以拿聚合函数作为判断条件了。在WHERE子句里面绝对不能写,只有在HAVING子句里面才可以这么写。
sql
select deptno from t_emp
group by deptno having avg(sal)>=2000
问题1:查询每个部门中,1982年以后入职员工超过2个人的部门编号
sql
select deptno
from t_emp
where hiredate>="1982-01-01"
group by deptno having count(*)>=2;
2. HAVING子句的特殊用法
这个SQL语句里边的group by子句并没有写分组的字段,只写了 1 这个 1 代表的是用select子句当中第一个字段作为分组字段
sql
select deptno,count(*)
from t_emp
group by 1 having deptno in(10,20)
这个HAVING子句。它是相当于WHERE子句的。所以说我们把WHERE子句拿掉,把WHERE子句的一些条件写在这里边。比如说是第一批deptno in 10,20,是想去判断一下这个10部门和20部门里边,按照这个部门编号的去分组,去统计一下两个部门里边员工的数量,只统计10和20部门的员工数量。正常情况下,我们如果不用HAVING的话,我们是可以用WHERE子句去定义这个条件的。这个判断条件写在HAVING子句里边也是可以的。最后我是建议大家,不要这么去写,为什么呢?因为这个WHERE子句它是先于group by子句执行的,它是先筛选一些数据,剩下的符合条件的数据,我们再去做分组,再去做聚合的统计计算。这个数据量就比较小了。但是如果我们把这个条件写在HAVING子句里边,这个group by做这个分组的时候,这个数据量还是很大的。你再去用这个HAVING子句筛选掉其他的这些数据,还是有点不值得的。你倒不如说写到WHERE子句里面,先筛选掉一大部分数据,少量的数据再进行分组,再拿这个聚合函数去执行统计一下。这样运行速度就比较快了。
将普通条件写在where子句里,这样运行的速度更快些
sql
select deptno,count(*)
from t_emp
where deptno in(10,20)
group by 1