1.知识点:可以对照下面的录屏进行阅读
SQL> --子查询所要解决的问题:问题不能一步求解
SQL> --查询工资比SCOTT高的员工信息
SQL> --(1)使用普通方法
SQL> --1. SCOTT的工资
SQL> select sal from emp where ename='SCOTT';
SQL> --2. 查询比3000高的员工
SQL> select *
2 from emp
3 where sal>3000;
SQL> --(2)使用子查询
SQL> select *
2 from emp
3 where sal > (select sal
4 from emp
5 where ename='SCOTT');
SQL> -- 注意的问题:
SQL> --1. 将子查询放入括号中
SQL> --2. 采用合理的书写风格
SQL> --3. 可以在主查询的where ,select ,from ,having后面,放置子查询
SQL> --4. 不可以在group by后面放置子查询
SQL> --5. 强调from后面放置子查询
SQL> --6. 主查询和子查询可以不是同一张表,只要子查询返回的结果,主查询可以使用,即可
SQL> --7. 一般不在子查询中使用order by;但在Top-N分析问题中,必须使用order by
SQL> --8. 一般先执行子查询,再执行主查询;但相关子查询除外
SQL> --9. 单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
SQL> --10. 注意子查询中null
SQL> --部分注意问题举例
SQL> --3. 可以在主查询的where select from having后面,放置子查询
SQL> --select
SQL> select ename,sal,(select job from emp where empno=7839) myjob
2 from emp;
SQL> --5. 强调from后面放置子查询
SQL> --查询员工的姓名和薪水
SQL> select *
2 from (select ename,sal from emp);
SQL> --6. 主查询和子查询可以不是同一张表,只要子查询返回的结果,主查询可以使用,即可
SQL> --查询部门名称为 SALES的员工信息
SQL> --子查询
SQL> select *
2 from emp
3 where deptno=(select deptno
4 from dept
5 where dname='SALES');
SQL> --多表查询
SQL> select e.*
2 from emp e,dept d
3 where e.deptno=d.deptno and d.dname='SALES';
SQL> --SQL优化: 如果子查询和多表查询都可以,理论上尽量使用多表查询
SQL> --多行操作符
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> --使用多表查询
SQL> select e.*
2 from emp e,dept d
3 where e.deptno=d.deptno and (d.dname='SALES' or d.dname='ACCOUNTING');
SQL> --any :和集合的任意一个值比较
SQL> --查询工资比30号部门任意一个员工高的员工信息
SQL> select *
2 from emp
3 where sal > any (select sal from emp where deptno=30);
SQL> --单行子查询的方法也可以解决这个问题
SQL>select *
2 from emp
3 where sal > (select min(sal) from emp where deptno=30)
SQL> --all :和集合的所有值比较
SQL> --查询工资比30号部门所有员工高的员工信息
SQL> select *
2 from emp
3 where sal > all (select sal from emp where deptno=30);
SQL> --单行子查询的方法也可以解决这个问题
SQL> select *
2 from emp
3 where sal > (select max(sal) from emp where deptno=30)
SQL> --多行子查询中null值问题
SQL> --集合中有null值不能使用not in,但可以使用in
SQL> --查询不是老板的员工信息
SQL> select *
2 from emp
3 where empno not in (select mgr from emp); --此查询没有结果,因为含有空值
SQL> --查询是老板的员工信息
SQL> select *
2 from emp
3 where empno in (select mgr from emp); --此查询结果正常
SQL> --原因:所有和空值比较的条件结果是空;
SQL> --使用not in方法的正确语句
SQL> select *
2 from emp
3 where empno not in (select mgr from emp where mgr is not null);
2.在Sqlplus下实际执行的结果录屏:
SQL> --查询工资比SCOTT高的员工信息
SQL> --1. SCOTT的工资
SQL> select sal from emp where ename='SCOTT';
SAL
----------
3000
SQL> --查询比3000高的员工
SQL> set linesize 120
SQL> col sal for 9999
SQL> select *
2 from emp
3 where sal>3000;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ----- ---------- ----------
7839 KING PRESIDENT 17-11月-81 5000 10
SQL> --子查询所要解决的问题:问题不能一步求解
SQL> select *
2 from emp
3 where sal > (select sal
4 from emp
5 where ename='SCOTT');
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ----- ---------- ----------
7839 KING PRESIDENT 17-11月-81 5000 10
SQL> /*
SQL> 注意的问题:
SQL> 1. 将子查询放入括号中
SQL> 2. 采用合理的书写风格
SQL> 3. 可以在主查询的where sele