Oracle_子查询

来源:互联网 发布:老七贸易 知乎 编辑:程序博客网 时间:2024/05/22 12:34

子查询所要解决的问题:问题不能一步求解
SQL> --查询工资比SCOTT高的员工信息
SQL> select *
  2  from emp
  3  where sal > (select sal
  4               from emp
  5               where ename='SCOTT');

注意的问题:
 1. 将子查询放入括号中
 2. 采用合理的书写风格
 3. 可以在主查询的where select from having后面,放置子查询
 4. 不可以在group by后面放置子查询
 5. 强调from后面放置子查询
 6. 主查询和子查询可以不是同一张表,只要子查询返回的结果,主查询可以使用,即可
 7. 一般不在子查询中使用order by;但在Top-N分析问题中,必须使用order by
 8. 一般先执行子查询,再执行主查询;但相关子查询除外
 9. 单行子查询只能使用单行操作符(>,<,=);多行子查询只能使用多行操作符(in,any,all)
 10. 注意子查询中null

在主查询的 select 后面,放置子查询
SQL> select ename,sal,(select job from emp where empno=7839) myjob
  2  from emp;

5. 强调from后面放置子查询
SQL> --查询员工的姓名和薪水
SQL> select *
  2  from (select ename,sal from emp);


6. 主查询和子查询可以不是同一张表,只要子查询返回的结果,主查询可以使用,即可
SQL> --查询部门名称为 SALES的员工信息
  1  select *
  2  from emp
  3  where deptno=(select deptno
  4                from dept
  5                where dname='SALES');
  1  select e.*
  2  from emp e,dept d
  3  where e.deptno=d.deptno and d.dname='SALES';(性能比前一句好)
  
SQL优化: 如果子查询和多表查询都可以,理论上尽量使用多表查询


多行操作符
--in :在集合中
SQL> --查询部门名称为SALES和ACCOUNTING的员工信息
SQL> select *
  2  from emp
  3  where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');

SQL> select e.*
  2  from emp e,dept d
  3  where e.deptno=d.deptno and (d.dname='SALES' or d.dname='ACCOUNTING');

--any 和集合的任意一个值比较
SQL> --查询工资比30号部门任意一个员工高的员工信息
SQL> select *
  2  from emp
  3  where sal > any (select sal from emp where deptno=30);
相当于:
  1  select *
  2  from emp
  3* where sal > (select min(sal) from emp where deptno=30)


--all 和集合的所有值比较
SQL> --查询工资比30号部门所有员工高的员工信息
SQL> select *
  2  from emp
  3  where sal > all (select sal from emp where deptno=30);
相当于:
  1  select *
  2  from emp
  3* where sal > (select max(sal) from emp where deptno=30)

--多行子查询中null值
SQL> select *
  2  from emp
  3  where empno not in (select mgr from emp);
未选定行-----》错误的结果:因为not in 之后的元素里面,每个元素的逻辑运算是and,
      即not in a and not in b and ...not in null
      只要有null值,则不会返回结果,其实是有结果的

--查询是老板的员工信息
  1  select *
  2  from emp
  3* where empno in (select mgr from emp)
------------》会产生正确结果:因为in之后的元素之间采用的是or逻辑运算
         即in a or in b or...in null
         即使有null值,但之前符合的结果还是会被正确返回

--查询不是老板的员工信息
SQL> select *
  2  from emp
  3  where empno not in (select mgr from emp where mgr is not null);