oracle子查詢

子查詢

所謂子查詢,實際上爲查詢的嵌套
當根據給出的條件沒法直接查出所須要的數據時,須要用到子查詢.函數

子查詢出現的位置

其中出現子查詢最多的位置:code

  • where
  • from

1用在where以後,做爲條件判斷;

查詢與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

2用在select以後,做爲select的內容;

查詢每一個部門的人數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

3能夠用在having以後,用做分組數據判斷的條件

查詢平均工資 少於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

4用在from以後,做爲一個結果集:

查詢最高工資的的五人的成績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

子查詢的使用方式

1子查詢返回單行單列

要求查詢公司工資最低的員工姓名,班組信息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

2子查詢返回單行多列

查詢出與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

3子查詢返回多行多列

在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

4exists

  • 用於檢查子查詢是否至少返回一行數據
  • 該子查詢實際上並不返回任何數據,而是返回值True和False

查詢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

rank() over

  • 查出指定條件後的進行排名

  • 使用這個函數,成績相同的兩名是並列,下一位同窗空出所佔的名次。

查詢各科成績前三名的記錄

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

dense_rank() over

與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

row_number

該函數不須要考慮是否並列,那怕根據條件查詢出來的數值相同也會進行連續排名

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
相關文章
相關標籤/搜索