一、子查询
select语句中嵌套select语句,被嵌套的select语句是子查询,子查询可以出现在select\from\where后面
select
……(select)
from
……(select)
where
……(select)
1、where后面加select子查询
示例1:
找出高于平均薪资的员工信息
第一步:找出平均薪资
select avg(sal) from emp;
第二步:使用where过滤
select * from emp where sal>(select avg(sal) from emp);
2、from后面加select子查询
示例2:
找出每个部门平均薪水的薪资等级
第一步:
先找出每个部门的平均薪资
select deptno,avg(sal) as avgsal from emp group by deptno;
执行后得到下面的结果,将得到的表看做一张临时新表t
。
第二步:
问题就变成在表t中avgsal字段介于哪个薪资等级,按照以往的写法
select t.*,s.grade from (上面的表) t join salgrade s on t.avgsal between s.losal and s.hisal;
将t换成第一步的查询语句即可完成.。
最终的写法:
select t.deptno,t.avgsal,s.grade
from
(select deptno,avg(sal) as avgsal from emp group by deptno) as t
join
salgrade as s
on
t.avgsal between s.losal and s.hisal;
示例3:
求每个部门员工薪资等级的平均等级
第一步:
求每个员工的薪资等级
第二步:
求每个部门的的平均薪资等级
①、select e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
②、在上面基础上对deptno
字段分组,在对grade
字段求平均值。这里也可以使用上面示例2的方法,将这张表看做新表继续使用select语句来查询,如下面这样
select
t.deptno,avg(t.grade)
from
( select
e.deptno,s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal
) t
group by
deptno;
针对于本题上面的嵌套查询显然效率低下,因为在第一步的时候已经得出表了,只需要按照deptno
字段分组,再求grade
字段的平均值就好了,没必要在select一次了,看下面的改进的方法
select
e.deptno,avg(s.grade)
from emp e
join salgrade s
on
e.sal between s.losal and s.hisal
group by deptno;
只在第一步后面加上group by分组,在select后面的s.grade字段求平均值就好了。没有上面嵌套的那么复杂,效率也高了。