学习子查询刚刚开始有点乱,多做题能让头脑的思路变得清晰,学习方法就是多练多想。
1、子查询
内部查询,放在括号里的查询。--分页查询一
select * from (select a1.*,rownum rn from (select * from student) a1 where rownum <=5) where rn>=2;
--分页查询二
select a1.* from (select student.*,rownum rn from student where rownum <=5) a1 where rn >=3;
--分页查询三
select a1.* from (select student.*,rownum rn from student) a1 where rn between 3 and 5;
WHERE e.deptno=a.deptno AND e.sal>a.avgsal
-----------------------------子查询---------------------------------------------
1.查询工资比jones高的员工信息
select * from emp where sal>(select sal from emp where ename='JONES')
select * from emp where sal=(select min(sal) from emp)
-----括号内的查询先执行,也就是子查询优于主查询执行---------------
------子查询使用的位置:where having from子句
------查询比30号部门员工工资都低的员工信息
------多行运算符和多行子查询------------------------------------------------------------------
select *
from emp
where sal
select *
from emp
where sal<(select min(sal) from emp where deptno=30);-----使用组函数实现功能
-----子查询的分类:单行,多行,多列
-----查询部门最低工资比20号部门最低工资高的部门编号和最低工资
select deptno,min(sal)
from emp
group by deptno
having min(sal)>(select min(sal) from emp where deptno=20)
-----如果子查询返回结果为空,怎么办?凉拌,可以执行
select * from emp where job=(select job from emp where ename='zhangsan');
----------------------------多行子查询,返回一行或者多行---------------------------------------------
in,any,all
-----查询和scott同一个部门的员工信息
select * from emp where deptno in(select deptno from emp where ename='SCOTT')
update emp
set sal=sal+1000
where empno in
(select empno from emp where sal in(select min(sal) from emp group by deptno))----子查询一定要用括号括起来
-------------------any的使用-------------
>any():大于最小的,大于其中任意一个就可以了,等同于>min()
select *
from emp
where sal
select *
from emp
where sal<(select max(sal) from emp where deptno=30)
------------------------all的使用--------------------
>all():大于最大的,就是比任何一个都要大才行,等同于:>max()
------------------------in的使用---------------------------------------
in 是等于任意一个的意思,等同于 =any()
-----------------------多列子查询----------------------------------------------
--需求:查出与allen的job,deptno相同的员工信息
----多个列之间可以进行比较:语法是(column1,column2)=(select column1,column2......)
select *
from emp
where (job,deptno) in (select job,deptno from emp where ename='ALLEN')---单行用=,多行用in
------找出不是经理的员工---------------------
select *
from emp
where empno not in(select distinct mgr from emp where mgr is not null);------------ 子查询中有空值,导致比较后为空
----因为所有的条件和空值比较,结果都是空值---,可以在后面加上where子句过滤掉空值
--练习1
--1.查询入职日期最早的员工姓名,入职日期
select ename,hiredate
from emp
where hiredate in (select min(emp.hiredate) from emp)
--2.查询工资比SMITH工资高并且工作地点在CHICAGO的员工姓名,工资,部门名称
select e.ename,e.sal,d.dname,d.loc
from emp e,dept d
where e.deptno=d.deptno and d.loc='CHICAGO' and e.sal>(
select sal
from emp
where ename='SMITH'
)
-- 3.查询入职日期比20部门入职日期最早的员工还
--要早的员工姓名,入职日期
select ename,hiredate
from emp
where emp.hiredate<(
select min(e.hiredate)
from emp e
where deptno=20
)
--4.查询部门人数大于所有部门平均人数的的部门
--编号,部门名称,部门人数
select e.deptno,d.dname,count(e.empno)
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno,d.dname
having count(empno)>(
select avg(count(empno))
from emp
group by emp.deptno
)
select empno,ename,job,sal
from emp
where sal>all(select sal from emp where deptno=10)
and deptno<>0
--练习2
--1.查询入职日期比10部门任意一个员工晚的员工姓名、入职日期,不包括10部门员工
select ename,hiredate
from emp
where hiredate>any(
select hiredate
from emp
where deptno=10
) and deptno<>10
--2.查询入职日期比10部门所有员工晚的员工姓名入职日期,不包括10部门员工
select ename,hiredate
from emp
where hiredate>all(
select hiredate
from emp
where deptno=10
) and deptno<>10
--3.查询职位和10部门任意一个员工职位相同的员工姓名,职位,不包括10部门员工
select job,ename
from emp
where job=any(
select job
from emp
where deptno=10
) and deptno<>10
--练习3
--1.查询职位及经理和10部门任意一个员工职位及
--经理相同的员工姓名,职位,不包括10部门员工
select ename,job
from emp
where (job,mgr)= any(
select job,mgr
from emp
where deptno=10
) and deptno<>10
--2.查询职位及经理和10部门任意一个员工职位或
--经理相同的员工姓名,职位,不包括10部门员工
select ename,deptno
from emp
where (job in
(select job from emp where deptno=10)
or
mgr in
(select mgr from emp where deptno=10 )
) and deptno<>10
--练习4
--1.查询比自己职位平均工资高的员工姓名、职位,部门名称,职位平均工资
select e1.ename,e1.job,d.dname,e2.mean_sal
from dept d,(select avg(sal) mean_sal,job from emp group by job) e2,emp e1
where d.deptno=e1.deptno and e1.sal>e2.mean_sal and e1.job=e2.job
-- 2.查询职位和经理同员工SCOTT或BLAKE完全相同的员工姓名、职位,不包括SCOOT和BLAKE本人。
select e1.ename,e1.job
from emp e1,(select job,mgr from emp where ename='SCOTT' or ename='BLAKE') e2
where (e1.job=e2.job and e1.mgr=e2.mgr) and e1.ename<>'SCOTT' and e1.ename<>'BLAKE'
--3.查询不是经理的员工姓名。
select ename
from emp
where empno not in(
select j.empno
from emp e,emp j
where e.mgr=j.empno
group by j.empno
)
--练习5
--1.查询入职日期最早的前5名员工姓名,入职日期。
select rownum,ename,hiredate
from emp
where rownum<6
order by hiredate
--2.查询工作在CHICAGO并且入职日期最早的前2名员工姓名,入职日期。
select rownum ,e.ename,e.hiredate
from emp e,dept d
where e.deptno=d.deptno and rownum<3 and d.loc='CHICAGO'
order by hiredate
--练习6
--1.按照每页显示5条记录,分别查询第1页,第2
--页,第3页信息,要求显示员工姓名、入职日期、部门名称。
select b.*
from (select rownum rn,e.ename,e.hiredate,d.dname
from emp e,dept d
where e.deptno=d.deptno
) b
where rn<=2*5 and rn>(2-1)*5
--练习7
--1.按照每页显示5条记录,分别查询工资最高的
--第1页,第2页,第3页信息,要求显示员工姓名、入职日期、部门名称、工资。
select *
from (select rownum rn,b.*
from (select e.ename,e.hiredate,d.dname,e.sal
from emp e,dept d
where e.deptno=d.deptno
order by e.sal desc
) b
where rownum<=2*5
)bb
where rownum>(2-1)*5
select * from
(
select rownum rn,b.*
from(select e.ename,e.hiredate,d.dname,e.sal
from emp e,dept d
where e.deptno=d.deptno
order by e.sal desc)b
where rownum<=2*5
)bb where rownum>=(2-1)*5
--课后作业
--1.查询工资高于编号为7782的员工工资,并且和7369号员
--工从事相同工作的员工的编号、姓名及工资。
select deptno,ename,sal
from emp
where sal> (select sal from emp where empno=7782)
and job in (select job from emp where empno=7369)
--2.查询工资最高的员工姓名和工资。
select sal,ename
from emp
where sal=(
select max(sal)
from emp
)
--3.查询部门最低工资高于10号部门最低工资的部门的编号、
--名称及部门最低工资。
select e1.deptno,d.dname,e1.pinjun
from (select min(sal) pinjun,deptno from emp group by deptno)e1,
(select min(sal) shihao from emp where deptno=10)e2,dept d
where e1.deptno=d.deptno and e1.pinjun>e2.shihao
--4.查询员工工资为其部门最低工资的员工的编号和姓名及工资。
select deptno,ename,sal
from emp
where sal in (select min(sal) from emp group by deptno )
--5.显示经理是KING的员工姓名,工资。
select ename,sal
from emp
where mgr=(select empno from emp where ename='KING')
--6.显示比员工SMITH参加工作时间晚的员工姓名,工资,参加工作时间。
select ename,sal,hiredate
from emp
where hiredate<(select hiredate from emp where ename='SMITH')
--课后作业
--7.使用子查询的方式查询哪些职员在NEW YORK工作。
select ename
from emp e,dept d
where e.deptno=d.deptno and d.loc='NEW YORK'
-- 8.写 个查询显示和员工SMITH工作在同 个部门的员工姓名,雇用日期,查询结果中排除SMITH。
select ename,hiredate
from emp
where deptno in(select deptno from emp where ename='SMITH')
and ename<>'SMITH'
--9.写一个查询显示其工资比全体职员平均工资高的员工编号、姓名。
select ename,empno
from emp
where sal>(select avg(sal) from emp )
--10.写一个查询显示其上级领导是King的员工姓名、工资。
select ename,sal
from emp
where mgr=(select empno from emp where ename='KING')
--11.显示所有工作在RESEARCH部门的员工姓名,职位。
select e.ename,e.job
from emp e,dept d
where e.deptno=d.deptno and d.dname='RESEARCH'
--12.查询每个部门的部门编号、平均工资,要求部门的平
--均工资高于部门20的平均工资。
select deptno,avg(sal)
from emp
where sal>(select avg(sal) from emp where deptno=20 )
group by deptno
--13.查询大于自己部门平均工资的员工姓名,工资,所在
--部门平均工资,高于部门平均工资的额度。
select e1.ename,e1.sal,e1.sal-e2.bumen 差额
from emp e1,(select avg(sal) bumen,deptno from emp group by deptno)e2
where e1.deptno=e2.deptno and e1.sal>e2.bumen
--课后作业
--14. 列出至少有一个雇员的所有部门
select deptno
from emp
where emp.empno<>0
group by deptno
--15. 列出薪金比 SMITH 多的所有雇员
select *
from emp
where sal>(select sal from emp where ename='SMITH')
--16. 列出入职日期早于其直接上级的所有雇员
select *
from emp e1,emp e2
where e1.mgr=e2.empno and e1.hiredate>e2.hiredate
--17. 找员工姓名和直接上级的名字
select e1.ename,e2.ename
from emp e1,emp e2
where e1.mgr=e2.empno
--18. 显示部门名称和人数
select d.dname,count(e.empno)
from emp e,dept d
where e.deptno=d.deptno
group by d.dname
--19. 显示每个部门的最高工资的员工
select max(e.sal),d.dname
from emp e,dept d
where e.deptno=d.deptno
group by d.dname
--20. 显示出和员工号7369部门相同的员工姓名,工资
select ename,sal
from emp
where deptno=(select deptno from emp where empno=7369)
--21. 显示出和姓名中包含"W"的员工相同部门的员工姓名
select ename,deptno
from emp
where deptno=(select deptno from emp where ename like '%W%')
--22. 显示出工资大于平均工资的员工姓名,工资
select ename,sal
from emp
where sal>(select avg(sal) from emp)
--23. 显示出工资大于本部门平均工资的员工姓名,工资
select e1.ename,e1.sal
from emp e1,(select deptno,avg(sal) pinjun from emp group by deptno) e2
where e1.deptno=e2.deptno and e1.sal>e2.pinjun
--24. 显示每位经理管理员工的最低工资,及最低工资者的姓名
SELECT outer.ENAME FROM EMP outer
WHERE outer.SAL =(SELECT MIN(SAL) FROM EMP inner where outer.mgr=inner.mgr);--这个地方是用到相关子查询
--用子查询的做法
select ename,empno
from emp
where sal in (select min(sal) from emp group by mgr ) and ename is not null
--25. 显示比工资最高的员工参加工作时间晚的员工姓名,参加工作时间
select ename,hiredate
from emp
where hiredate<(select hiredate from emp where sal=(select max(sal) from emp) )
--26. 显示出平均工资最高的的部门平均工资及部门名称
select d.dname,e.zuida
from (select max(sal) zuida,deptno
from emp
group by deptno
order by max(sal) desc) e,dept d
where e.deptno=d.deptno and rownum=1