子查询的位置:
1.select关键词后
2.fom关键词后(内嵌试图)
3.where关键词后
4.having关键词后
一个子查询的结果可以是:
1.一张表
2.一行
3.一个值
子查询必须用"()"括起来
子查询的分类:
1.标准子查询:本身执行过程和外界没有任何联系,子查询首先执行一次,把结果反馈给外查询,外查询把他当成一个常量。
谁的工资是最低的
select e.empno,e.ename,e.sal from emp e where e.sal=(select min(sal) from emp);
2.关联子查询:子查询在执行过程中和外查询发生关系,执行条件的子查询随着外查询的指针每移动一次子查询就执行一次。会反复循环加以执行
特别耗费资源。
哪些人的工资比本部门的平均工资高
1)select e.empno,e.ename,e.sal from emp e where e.sal>(select avg(nvl(sal,0)) from emp where emp.deptno=e.deptno );
关联子查询效率低
2)select e.empno,e.ename,e.sal from emp e ,(select deptno,avg(nvl(sal,0)) avgdept from emp group by deptno) d where e.deptno=d.deptno and e.sal>d.avgdept;
内嵌试图效率高
注意:d.avgdept不能写成d.avg(nvl(sal,0)) 否则系统无法识别。
返回结果是一行的子查询使用单行条件连接符(=,<,>!,!=等)
谁的工资是最低的
select e.empno,e.ename,e.sal from emp e where e.sal=(select min(sal) from emp);
返回结果多余一行的子查询使用多行条件连接符(in,any,all,exists)
in表示匹配所有子查询返回结果
select e.empno,e.ename,e.sal from emp e where e.sal not in(select sal from emp where emp.job='SALESMAN');
EMPNO ENAME SAL
---------- ---------- ----------
7369 SMITH 800
7566 JONES 2975
7698 BLAKE 2850
7782 CLARK 2450
7788 SCOTT 3000
7839 KING 5000
7876 ADAMS 1100
7900 JAMES 950
7902 FORD 3000
7934 MILLER 1300
特别注意:
not in 后面的子查询不能返回null
1)找出是领导的员工
SQL> select e.empno,e.ename,e.job from emp e where e.empno in(select distinct mgr from emp);
EMPNO ENAME JOB
---------- ---------- ---------
7566 JONES MANAGER
7698 BLAKE MANAGER
7782 CLARK MANAGER
7788 SCOTT ANALYST
7839 KING PRESIDENT
7902 FORD ANALYST
6 rows selected.
2)找出不是领导的员工
SQL> select e.empno,e.ename,e.job from emp e where e.empno not in(select distinct mgr from emp);
no rows selected
注意得到任何结果要清楚子查询返回的null记录
SQL> select e.empno,e.ename,e.job from emp e where e.empno not in(select distinct mgr from emp where mgr is not null);
SQL> select e.empno,e.ename,e.job from emp e where e.empno not in(select distinct mgr from emp where mgr is not null);
EMPNO ENAME JOB
---------- ---------- ---------
7369 SMITH CLERK
7499 ALLEN SALESMAN
7521 WARD SALESMAN
7654 MARTIN SALESMAN
7844 TURNER SALESMAN
7876 ADAMS CLERK
7900 JAMES CLERK
7934 MILLER CLERK
8 rows selected.
这是为什么那?
1.in 子查询的逻辑关系
X==a or X==b or x==c ..... or x==null
任何值和null比较结果null, 由于是OR语句只要一个为真结果就为真, 所以只看前半部分 null值忽略
2.not in子查询的逻辑关系
X!=a and X!=b and x!=c ..... and x!=null
同理任何值和null比较结果null, 由于是and语句短路原理,只要一个为假结果为假, 所以结果必为null/FALSE
由此可见在in 子查询结果列表中含有null值时,不影响正常比较
而在not in 子查询结果列表中含有null值时,必然返回空,就算有项目符合前面所有结果
any表示能匹配任意一个子查询返回结果
比任何一个工种是SALESMAN工资高的员工
SQL> select e.empno,e.ename,e.sal,e.job from emp e where e.sal > any (select sal from emp where emp.job='SALESMAN');
EMPNO ENAME SAL JOB
---------- ---------- ---------- ---------
7839 KING 5000 PRESIDENT
7902 FORD 3000 ANALYST
7788 SCOTT 3000 ANALYST
7566 JONES 2975 MANAGER
7698 BLAKE 2850 MANAGER
7782 CLARK 2450 MANAGER
7499 ALLEN 1600 SALESMAN
7844 TURNER 1500 SALESMAN
7934 MILLER 1300 CLERK
all表示必须匹配所有子查询返回结果
比所有工种是SALESMAN工资高的员工
SQL> 1* select e.empno,e.ename,e.sal,e.job from emp e where e.sal > all (select sal from emp where emp.job='SALESMAN')
EMPNO ENAME SAL JOB
---------- ---------- ---------- ---------
7566 JONES 2975 MANAGER
7698 BLAKE 2850 MANAGER
7782 CLARK 2450 MANAGER
7788 SCOTT 3000 ANALYST
7839 KING 5000 PRESIDENT
7902 FORD 3000 ANALYST
6 rows selected.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/20844861/viewspace-594624/ ,如需转载,请注明出处,否则将追究法律责任。