文章目录
一、为什么要学习子查询?
示例:查询工资比scott高的员工信息?
--1.SCOTT的工资
select sal from emp where ename='SCOTT';
--2.比3000高的员工信息
select * from emp where sal > 3400;
二、子查询概述
使用子查询解决问题:
谁的工资比SCOTT高?
三、子查询的使用
1、子查询的语法:
SELECT select_list
FROM table
WHERE expr operator
(SELECT select_list
FROM table);
2、使用子查询解决刚才的问题
示例:谁的工资比SCOTT高?
select * from emp
where sal > (select sal from emp where ename = 'SCOTT');
四、子查询注意的10个问题
1、子查询语法中的小括号
SELECT select_list
FROM table
WHERE expr operator
(SELECT select_list
FROM table);
2、子查询的书写风格
3、可以使用子查询的位置:where
,select
,having
,from
select empno,ename,sal,(select empjob from emp where empno=7839) 职位列
from emp;
select deptno,avg(sal)
from emp
group by deptno
having avg(sal) < (select max(sal)
from emp
where deptno = 30);
select *
from(select empno,ename,sal from emp);
4、不可以使用子查询的位置:group by
select avg(sal)
from emp
group by (select deptno from emp);
5、强调:from后面的子查询
示例1:查询员工信息:员工号,姓名,月薪
select *
from(select empno,ename,sal from emp);
示例2:查询员工信息:员工号,姓名,月薪,年薪
select *
from(select empno,ename,sal,sal*12 annsal from emp);
6、主查询和子查询可以不是同一张表
示例:查询部门名称是SALES的员工信息
select *
from emp
where deptno =(select deptno
from dept
where dname = 'SALES');
以下为多表查询解决相同问题
select e.*
from emp e, dept d
where e.deptno = d.deptno and d.dname = 'SALES';
7、一般不在子查询中,使用排序;当在Top-N分析问题中,必须对子查询排序
示例:找到员工表中工资最高的前三名
rownum伪列
select rownum,empno,ename,sal
from (select *
from emp
order by sal desc)
where rownum <= 3;
行号需要注意的两个问题
- 行号永远按照默认的顺序生成
- 行号只能使用<,<=;不能使用>,>=
8、一般先执行子查询,再执行主查询;但相关子查询例外
示例:找到员工表中薪水大于本部门平均薪水的员工
select empno,ename,sal,(select avg(sal) from emp where deptno = e.deptno) avgsal
from emp e
where sal>(select avg(sal) from emp where deptno = e.deptno);
9、单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
10、注意:子查询中的null值问题
(1)单行子查询中的null值问题
(2)多行子查询中的null值问题
五、子查询的类型
1、单行子查询
(1)单行子查询
(2)单行操作符
(3)单行子查询
示例1:查询员工信息,要求:
职位与7566员工一样
薪水大于7782员工的薪水
select *
from emp
where empjob = (select empjob from emp where empno = 7566)
and sal > (select sal from emp where empno = 7782);
示例2:查询工资最低的员工信息
select *
from emp
where sal = (select min(sal) from emp);
示例3:查询最低工资大于20号部门最低工资的部门号和部门的最低工资
select deptno,min(sal)
from emp
group by deptno
having min(sal) > (select min(sal)
from emp
where deptno = 20);
(4)非法使用单行子查询
查询最低工资大于20号部门最低工资的部门号和部门的最低工资
select empno,ename
from emp
where sal = (select min(sal)
from emp
group by deptno);
(5)单行子查询中的null值问题
子查询不返回任何行
select ename,empjob
from emp
where empjob = (select empjob from emp where ename = 'Tom');
2、多行子查询
(1)多行子查询
(2)多行操作符
多行操作符in
示例:查询部门名称是SALES和ACCOUNTING的员工信息
select *
from emp
where deptno in (select deptno from dept where dname = 'SALES' or dname = 'ACOUNTING');
多行操作符any
示例:查询工资比30号部门任意一个员工高的员工信息
select *
from emp
where sal < any(select sal from emp where deptno=30);
多行操作符all
示例:查询工资比30号部门所有员工高的员工信息
select *
from emp
where sal > all(select sal from emp where deptno=30);
(3)多行子查询中的null值问题
示例:查询不是老板的员工
select *
from emp
where empno not in (select mgr
from emp
where mgr is not null);