SQL子查询

SQL子查询。

一、非关联子查询

(一)子查询

就是在一条SQL语句中嵌入另一条SQL语句

select sal from emp
where ename='FORD';

select sal from emp
where sal>300;

select ename from emp
where sal>(select sal from emp where ename='FORD');

1.先执行子查询,子查询的返回结果作为主查询的条件,再执行主查询

2.子查询只执行一遍

3.若子查询的返回结果为多个值,Oracle会去掉重复值之后,再将结果返回给主查询

4.子查询常见错误

(1)比较运算符的选择

(2)若 子查询的返回结果仅为一个值,可用单值运算符,如=,>, <, >=, <=

(3)若子查询的返回结果可能为多值,必须用多值运算符,如IN等

5.若子查询的返回结果中包含空值NULL,并且运算符为NOT IN,那么整个查询不会返回任何行。NOT IN等价于<>ALL,任何值跟NULL比(包括NULL本身),结果都不为TRUE

(二)多列子查询

每个部门薪水最高的人

select deptno,ename,sal
from emp
where(deptno,sal) in (select deptno,max(sal) sal
                                 from emp
                                 group by deptno);

(三)having子句中包含子查询

select deptno
from emp
group by deptno
having avg(sal)>(select avg(sal) 
                          from emp 
                          where deptno=20);

二、关联子查询

select c1,c2
from t1 outer
where c1 operator(select c1,c2 
                            from tables 
                            where expr1=outer.expr2);

哪些员工的薪水比本部门的平均薪水高

select ename,sal,deptno
from emp outer
where sal>(select avg(sal)
                  from emp 
                  where deptno=outer.deptno);

(一)关联子查询的执行过程

关联子查询采用的是循环的方式,执行步骤如下:

1.外部查询得到一条记录(查询先从outer表中读取数据),并将其传入到内部查询

2.内部查询基于传入的值执行

3.内部查询从其结果中把值传回到外部查询,外部查询使用这些值来完成其处理,若符合条件,outer表中得到的那条记录就放入结果集中,否则放弃,该记录不符合条件

4.重复1~3步,直到把outer表中的所有记录判断一遍

(二)exists运算符

select ename,job,deptno
from emp outer
where exists(select 'x' 
                    from emp 
                    where mgr=outer.empno);

1.exists的执行过程

exists采用的是循环方式,判断outer表中是否存在记录,只要在innner表中找到一条匹配的记录即可

(1)外部记录得到一条记录(查询先从outer表中读取数据)并将其传入到内部查询的表

(2)对innner表中的记录依次扫描,若根据条件存在一条记录与outer表中的记录匹配,立即停止扫描,返回true,将outer表中的记录放入结果集中,若扫描了全部记录,没有任何一条记录符合匹配条件,返回false,outer表中的该记录被过滤掉,不能出现在结果集中

(3)重复(1)(2),直到把outer表中的所有记录判断一遍

(三)not exists

查询出没有员工的部门

select deptno,dname
from dept outer
where not exists(select 'x' 
                          from emp 
                          where deptno=outer.deptno);

(四)IN和EXISTS的比较

EXISTS是用循环的方式,由outer表的记录数决定循环的次数,对于exists影响最大,所以,外表的记录数要少

IN先执行子查询,子查询的返回结果去重之后,再执行主查询,所以,子查询的返回结果越少,越适合用该方式。

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐