所謂子查詢,實際上爲查詢的嵌套
當根據給出的條件沒法直接查出所須要的數據時,須要用到子查詢.函數
其中出現子查詢最多的位置:code
查詢與7369同部門的全部人排序
SQL> select empno,ename,deptno 2 from emp 3 where deptno= 4 (select deptno from emp where empno=7369); EMPNO ENAME DEPTNO ---------- -------------------- ---------- 7777 S_HH%GGH 20 7369 SMITH 20 7566 JONES 20 7788 SCOTT 20 7876 ADAMS 20 7902 FORD 20
查詢每一個部門的人數it
SQL> select 2 (select count(1) from emp where deptno=10) "10", 3 (select count(1) from emp where deptno=20) "20", 4 (select count(1) from emp where deptno=30) "30" 5 from dual; 10 20 30 ---------- ---------- ---------- 3 6 6
查詢平均工資 少於20組的平均工資 的班組io
SQL> select deptno, avg(sal) 2 from emp 3 group by deptno 4 having avg(sal) > 5 (select avg(sal) from emp where deptno = 20); DEPTNO AVG(SAL) ---------- ---------- 10 2916.66667
查詢最高工資的的五人的成績ast
SQL> select * 2 from (select sal from emp where sal > 0 order by sal desc) 3 where rownum < 6; SAL ---------- 5000 3000 3000 2975 2850
要求查詢公司工資最低的員工姓名,班組信息date
第一步:統計出公司的最低工資select
SQL> select min(sal) from emp; MIN(SAL) ---------- 800
第二步:上面會返回單行單列數據,是一個數值.
再進行where條件判斷統計
SQL> select ename,job,deptno from emp 2 where sal=(select min(sal) from emp); ENAME JOB DEPTNO -------------------- ------------------ ---------- SMITH CLERK 20
查詢公司僱傭最先的僱員數據
僱傭最先必定是僱員日期最小,那麼使用MIN()函數完成
SQL> select min(hiredate) from emp; MIN(HIREDATE) -------------- 17-12月-80
返回單行單列的數據,全部能夠直接在WHERE子句中使用
SQL> select empno,ename,hiredate from emp 2 where hiredate=(select min(hiredate) from emp); EMPNO ENAME HIREDATE ---------- -------------------- -------------- 7369 SMITH 17-12月-80
查詢出與SMITH部門相同、職位相同的全部僱員的編號姓名信息
首先應該查詢SMITH的部門與職位
SQL> select deptno,job from emp 2 where ename='SMITH'; DEPTNO JOB ---------- ------------------ 20 CLERK
此時返回了單行兩列的數據信息,要進行比較時要同時知足
SQL> select empno,ename,deptno,job from emp 2 where (deptno,job)=( 3 select deptno,job from emp where ename='SMITH'); EMPNO ENAME DEPTNO JOB ---------- -------------------- ---------- ------------------ 7777 S_HH%GGH 20 CLERK 7369 SMITH 20 CLERK 7876 ADAMS 20 CLERK
在WHERE子句中提供有三個主要的運算符:IN、ANY、ALL
SQL> select * from sc; SNO CNO SCORE -------------------- -------------------- ---------- s001 c001 78.9 s002 c001 80.9 s003 c001 81.9 s004 c001 60.9 s001 c002 82.9 s002 c002 72.9 s003 c002 81.9 s001 c003 59
查詢c001課程比c002課程成績高的全部學生的學號
SQL> select sno 2 from sc t1 3 where t1.cno='c001' 4 and sno in 5 (select sno from sc where 6 cno='c002' and t1.score>score and t1.sno=sno); SNO -------------------- s002
查詢c001課程比c002課程成績高的全部學生的學號
SQL> select sno 2 from sc t1 3 where t1.cno='c001' 4 and exists( 5 select * from sc where 6 cno='c002' and t1.sno=sno and t1.score>score); SNO -------------------- s002
SQL> select * from sc; SNO CNO SCORE -------------------- -------------------- ---------- s001 c001 78.9 s002 c001 80.9 s003 c001 81.9 s004 c001 60.9 s001 c002 82.9 s002 c002 72.9 s003 c002 81.9 s001 c003 59 s004 c002 81.9
查出指定條件後的進行排名
使用這個函數,成績相同的兩名是並列,下一位同窗空出所佔的名次。
查詢各科成績前三名的記錄
SQL> select cno,sno,score, 2 rank() over(partition by cno order by score desc) ranks from sc; CNO SNO SCORE RANKS -------------------- -------------------- ---------- ---------- c001 s003 81.9 1 c001 s002 80.9 2 c001 s001 78.9 3 c001 s004 60.9 4 c002 s001 82.9 1 c002 s003 81.9 2 c002 s004 81.9 2 c002 s002 72.9 4 c003 s001 59 1
SQL> select cno,sno,score from 2 (select cno,sno,score,rank() over(partition by cno order by score desc) rank from sc) 3 where rank<4; CNO SNO SCORE -------------------- -------------------- ---------- c001 s003 81.9 c001 s002 80.9 c001 s001 78.9 c002 s001 82.9 c002 s003 81.9 c002 s004 81.9 c003 s001 59
使用rank over()的時候,空值是最大的,若是排序字段爲null, 可能形成null字段排在最前面,影響排序結果。
SQL> select deptno,comm, 2 dense_rank() over(partition by deptno order by comm desc) ranks 3 from emp 4 where deptno=30; DEPTNO COMM RANKS ---------- ---------- ---------- 30 1 30 1 30 1400 2 30 500 3 30 300 4 30 0 5
SQL> select deptno,comm, 2 dense_rank() over(partition by deptno order by comm desc nulls last) ranks 3 from emp 4 where deptno=30; DEPTNO COMM RANKS ---------- ---------- ---------- 30 1400 1 30 500 2 30 300 3 30 0 4 30 5 30 5
與rank() over的區別是:
兩名學生的成績並列之後,下一位同窗並不空出所佔的名次。
SQL> select cno,sno,score, 2 dense_rank() over(partition by cno order by score desc) ranks from sc; CNO SNO SCORE RANKS -------------------- -------------------- ---------- ---------- c001 s003 81.9 1 c001 s002 80.9 2 c001 s001 78.9 3 c001 s004 60.9 4 c002 s001 82.9 1 c002 s003 81.9 2 c002 s004 81.9 2 c002 s002 72.9 3 c003 s001 59 1
SQL> select cno,sno,score from 2 (select cno,sno,score,dense_rank() over(partition by cno order by score desc) rank from sc) 3 where rank<4; CNO SNO SCORE -------------------- -------------------- ---------- c001 s003 81.9 c001 s002 80.9 c001 s001 78.9 c002 s001 82.9 c002 s003 81.9 c002 s004 81.9 c002 s002 72.9 c003 s001 59
該函數不須要考慮是否並列,那怕根據條件查詢出來的數值相同也會進行連續排名
SQL> select cno,sno,score, 2 row_number() over(partition by cno order by score desc) ranks from sc; CNO SNO SCORE RANKS -------------------- -------------------- ---------- ---------- c001 s003 81.9 1 c001 s002 80.9 2 c001 s001 78.9 3 c001 s004 60.9 4 c002 s001 82.9 1 c002 s003 81.9 2 c002 s004 81.9 3 c002 s002 72.9 4 c003 s001 59 1
SQL> select cno,sno,score from 2 (select cno,sno,score,row_number() over(partition by cno order by score desc) ranks from sc) 3 where ranks<4; CNO SNO SCORE -------------------- -------------------- ---------- c001 s003 81.9 c001 s002 80.9 c001 s001 78.9 c002 s001 82.9 c002 s003 81.9 c002 s004 81.9 c003 s001 59