欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL子查询

程序员文章站 2022-10-19 10:46:15
SQL子查询。 一、非关联子查询 (一)子查询 就是在一条SQL语句中嵌入另一条SQL语句 select sal from emp where ename='...
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先执行子查询,子查询的返回结果去重之后,再执行主查询,所以,子查询的返回结果越少,越适合用该方式。