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 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; ENAME SAL MYJOB ---------- ----- --------- SMITH 800 PRESIDENT ALLEN 1600 PRESIDENT WARD 1250 PRESIDENT JONES 2975 PRESIDENT MARTIN 1250 PRESIDENT BLAKE 2850 PRESIDENT CLARK 2450 PRESIDENT SCOTT 3000 PRESIDENT KING 5000 PRESIDENT TURNER 1500 PRESIDENT ADAMS 1100 PRESIDENT ENAME SAL MYJOB ---------- ----- --------- JAMES 950 PRESIDENT FORD 3000 PRESIDENT MILLER 1300 PRESIDENT 已選擇14行。 SQL> --5. 強調from後面放置子查詢 SQL> --查詢員工的姓名和薪水 SQL> select * 2 from (select ename,sal from emp); ENAME SAL ---------- ----- SMITH 800 ALLEN 1600 WARD 1250 JONES 2975 MARTIN 1250 BLAKE 2850 CLARK 2450 SCOTT 3000 KING 5000 TURNER 1500 ADAMS 1100 ENAME SAL ---------- ----- JAMES 950 FORD 3000 MILLER 1300 已選擇14行。 SQL> --6. 主查詢和子查詢可以不是同一張表,只要子查詢返回的結果,主查詢可以使用,即可 SQL> --查詢部門名稱為 SALES的員工信息 SQL> select * 2 from emp 3 where deptno=(select deptno 4 from emp 5 where dname='SALES'); where dname='SALES') * 第 5 行出現錯誤: ORA-00904: "DNAME": 標識符無效 SQL> ed 已寫入 file afiedt.buf 1 select * 2 from emp 3 where deptno=(select deptno 4 from dept 5* where dname='SALES') SQL> / EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7900 JAMES CLERK 7698 03-12月-81 950 30 已選擇6行。 SQL> select e.* 2 from emp e,dept d 3 where e.deptno=d.deptno and d.dname='SALES'; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7900 JAMES CLERK 7698 03-12月-81 950 30 已選擇6行。 SQL> --SQL優化: 如果子查詢和多表查詢都可以,理論上盡量使用多表查詢 SQL> host cls 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'); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7839 KING PRESIDENT 17-11月-81 5000 10 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7900 JAMES CLERK 7698 03-12月-81 950 30 7934 MILLER CLERK 7782 23-1月 -82 1300 10 已選擇9行。 SQL> select e.* 2 from emp e,dept d 3 where e.deptno=d.deptno and (d.dname='SALES' or d.dname='ACCOUNTING'); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7839 KING PRESIDENT 17-11月-81 5000 10 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7900 JAMES CLERK 7698 03-12月-81 950 30 7934 MILLER CLERK 7782 23-1月 -82 1300 10 已選擇9行。 SQL> host cla SQL> host cls SQL> --any 和集合的任意一個值比較 SQL> --查詢工資比30號部門任意一個員工高的員工信息 SQL> select * 2 from emp 3 where sal > any (select sal from emp where deptno=30); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7839 KING PRESIDENT 17-11月-81 5000 10 7902 FORD ANALYST 7566 03-12月-81 3000 20 7788 SCOTT ANALYST 7566 13-7月 -87 3000 20 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7934 MILLER CLERK 7782 23-1月 -82 1300 10 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7876 ADAMS CLERK 7788 13-7月 -87 1100 20 已選擇12行。 SQL> ed 已寫入 file afiedt.buf 1 select * 2 from emp 3* where sal > (select min(sal) from emp where deptno=30) SQL> / EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7788 SCOTT ANALYST 7566 13-7月 -87 3000 20 7839 KING PRESIDENT 17-11月-81 5000 10 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7876 ADAMS CLERK 7788 13-7月 -87 1100 20 7902 FORD ANALYST 7566 03-12月-81 3000 20 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7934 MILLER CLERK 7782 23-1月 -82 1300 10 已選擇12行。 SQL> --all 和集合的所有值比較 SQL> --查詢工資比30號部門所有員工高的員工信息 SQL> select * 2 from emp 3 where sal > all (select sal from emp where deptno=30); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7788 SCOTT ANALYST 7566 13-7月 -87 3000 20 7839 KING PRESIDENT 17-11月-81 5000 10 7902 FORD ANALYST 7566 03-12月-81 3000 20 SQL> ed 已寫入 file afiedt.buf 1 select * 2 from emp 3* where sal > (select max(sal) from emp where deptno=30) SQL> / EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7788 SCOTT ANALYST 7566 13-7月 -87 3000 20 7839 KING PRESIDENT 17-11月-81 5000 10 7902 FORD ANALYST 7566 03-12月-81 3000 20 SQL> host cls SQL> --多行子查詢中null值 SQL> --查詢不是老板的員工信息 SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7369 SMITH CLERK 7902 17-12月-80 800 20 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 7788 SCOTT ANALYST 7566 13-7月 -87 3000 20 7839 KING PRESIDENT 17-11月-81 5000 10 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7876 ADAMS CLERK 7788 13-7月 -87 1100 20 EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7900 JAMES CLERK 7698 03-12月-81 950 30 7902 FORD ANALYST 7566 03-12月-81 3000 20 7934 MILLER CLERK 7782 23-1月 -82 1300 10 已選擇14行。 SQL> select * 2 from emp 3 where empno not in (select mgr from emp); 未選定行 SQL> --查詢是老板的員工信息 SQL> ed 已寫入 file afiedt.buf 1 select * 2 from emp 3* where empno in (select mgr from emp) SQL> / EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7902 FORD ANALYST 7566 03-12月-81 3000 20 7698 BLAKE MANAGER 7839 01-5月 -81 2850 30 7839 KING PRESIDENT 17-11月-81 5000 10 7566 JONES MANAGER 7839 02-4月 -81 2975 20 7788 SCOTT ANALYST 7566 13-7月 -87 3000 20 7782 CLARK MANAGER 7839 09-6月 -81 2450 10 已選擇6行。 SQL> select * 2 from emp 3 where empno not in (select mgr from emp where mgr is not null); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- ---------- --------- ---------- -------------- ----- ---------- ---------- 7844 TURNER SALESMAN 7698 08-9月 -81 1500 0 30 7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30 7654 MARTIN SALESMAN 7698 28-9月 -81 1250 1400 30 7499 ALLEN SALESMAN 7698 20-2月 -81 1600 300 30 7934 MILLER CLERK 7782 23-1月 -82 1300 10 7369 SMITH CLERK 7902 17-12月-80 800 20 7876 ADAMS CLERK 7788 13-7月 -87 1100 20 7900 JAMES CLERK 7698 03-12月-81 950 30 已選擇8行。 SQL> spool off