Oracle数据库——ROWNUM

Oracle数据库——ROWNUM

前言

  刚学到了ROWNUM的用法,网上一搜,结果发现了有很多帖子,写的都很全。本着好记性不如烂笔头的原则,我还是决定自己手打一遍,当然下面也附上了我参考的链接。你可以尽情学习。

参考博客

一叶笑天的博客
IT·达人的博客
Cadence_D的博客

正题

  这里以SCOTT用户已经创建好了的EMP表来说明,EMP表结构如下【结果1】:

SQL> DESC EMP;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 EMPNO                                     NOT NULL NUMBER(4)
 ENAME                                              VARCHAR2(10)
 JOB                                                VARCHAR2(9)
 MGR                                                NUMBER(4)
 HIREDATE                                           DATE
 SAL                                                NUMBER(7,2)
 COMM                                               NUMBER(7,2)
 DEPTNO                                             NUMBER(2)
  EMP表有8列,这里只选取其中的三列(EMPNO,ENAME,SAL)分别是(编号,姓名,工资)来说明,按照工资降序查询结果如下【结果2】:
SQL> SELECT EMPNO,ENAME,SAL FROM EMP ORDER BY SAL DESC;

     EMPNO ENAME             SAL
---------- ---------- ----------
      7839 KING             5000
      7902 FORD             3000
      7788 SCOTT            3000
      7566 JONES            2975
      7698 BLAKE            2850
      7782 CLARK            2450
      7499 ALLEN            1600
      7844 TURNER           1500
      7934 MILLER           1300
      7521 WARD             1250
      7654 MARTIN           1250
      7876 ADAMS            1100
      7900 JAMES             950
      7369 SMITH             800

已选择14行。
1、 查询工资最高的员工

  嵌套查询,内层SELECT语句将EMP表按照工资的降序排序,外层SELECT语句从排序的表中取出第一条记录。查询语句如下,【代码3】:

SELECT *
FROM (
        SELECT EMPNO,ENAME,SAL
        FROM EMP
        ORDER BY SAL DESC
)
WHERE ROWNUM=1;

  查询结果如下,【结果3】:

SQL> SELECT *
  2  FROM (
  3          SELECT EMPNO,ENAME,SAL
  4          FROM EMP
  5          ORDER BY SAL DESC
  6  )
  7  WHERE ROWNUM=1;

     EMPNO ENAME             SAL
---------- ---------- ----------
      7839 KING             5000
2、查询工资排名第5名的员工(降序)

  使用3层嵌套查询。第1层(最里层)SELECT语句将EMP表按照工资降序排序,第2层(中间层)将排序好的表重新生成伪列,并增加ROWNUM伪列,别名为NO,第3层(最外层)取出生成伪列后的表的第5条记录即为所查询的人。【代码4】:

SELECT EMPNO,ENAME,SAL
FROM (
        SELECT ROWNUM NO,EMPNO,ENAME,SAL
        FROM (
                SELECT EMPNO,ENAME,SAL
                FROM EMP
                ORDER BY SAL DESC
        )
)
WHERE NO=5;

  查询结果如下,【结果4】:

SQL> SELECT EMPNO,ENAME,SAL
  2  FROM (
  3          SELECT ROWNUM NO,EMPNO,ENAME,SAL
  4          FROM (
  5                  SELECT EMPNO,ENAME,SAL
  6                  FROM EMP
  7                  ORDER BY SAL DESC
  8          )
  9  )
 10  WHERE NO=5;

     EMPNO ENAME             SAL
---------- ---------- ----------
      7698 BLAKE            2850
3、查询工资最高的前5名员工

  第1层SELECT语句将EMP表按照工资降序排序,第2层语句从排好序的表中取出前面5行记录。【代码5】:

SELECT *
FROM (
        SELECT EMPNO,ENAME,SAL
        FROM EMP
        ORDER BY SAL DESC
)
WHERE ROWNUM<6;

  查询结果如下,【结果5】:

SQL> SELECT *
  2  FROM (
  3          SELECT EMPNO,ENAME,SAL
  4          FROM EMP
  5          ORDER BY SAL DESC
  6  )
  7  WHERE ROWNUM<6;

     EMPNO ENAME             SAL
---------- ---------- ----------
      7839 KING             5000
      7788 SCOTT            3000
      7902 FORD             3000
      7566 JONES            2975
      7698 BLAKE            2850
4、查询工资最高的第5至9名员工

  第1层SELECT语句将EMP表按照工资降序排序,第2层取出排序好的前9行记录,第3层取出这9行记录中的后面5行记录即为查询结果。【代码6】:

SELECT EMPNO,ENAME,SAL
FROM (
        SELECT ROWNUM NO,EMPNO,ENAME,SAL
        FROM (
                SELECT EMPNO,ENAME,SAL
                FROM EMP
                ORDER BY SAL DESC
        )
        WHERE ROWNUM<10
)
WHERE NO>4;

  查询结果如下,【结果6】:

SQL> SELECT EMPNO,ENAME,SAL
  2  FROM (
  3          SELECT ROWNUM NO,EMPNO,ENAME,SAL
  4          FROM (
  5                  SELECT EMPNO,ENAME,SAL
  6                  FROM EMP
  7                  ORDER BY SAL DESC
  8          )
  9          WHERE ROWNUM<10
 10  )
 11  WHERE NO>4;

     EMPNO ENAME             SAL
---------- ---------- ----------
      7698 BLAKE            2850
      7782 CLARK            2450
      7499 ALLEN            1600
      7844 TURNER           1500
      7934 MILLER           1300

  看完上面的4道例题,不知道各位有没有看出点端倪来。如果没有继续看下面的例题

5、查询工资最高的第2名员工

  同第2题。【代码7】:

SELECT EMPNO,ENAME,SAL
FROM (
        SELECT ROWNUM NO,EMPNO,ENAME,SAL
        FROM (
                SELECT EMPNO,ENAME,SAL
                FROM EMP
                ORDER BY SAL DESC
        )
)
WHERE NO=2;

  查询结果如下,【结果7】:

SQL> SELECT EMPNO,ENAME,SAL
  2  FROM (
  3          SELECT ROWNUM NO,EMPNO,ENAME,SAL
  4          FROM (
  5                  SELECT EMPNO,ENAME,SAL
  6                  FROM EMP
  7                  ORDER BY SAL DESC
  8          )
  9  )
 10  WHERE NO=2;

     EMPNO ENAME             SAL
---------- ---------- ----------
      7902 FORD             3000

  OK,你确定是这1条记录吗?其实有2名员工的工资都是3000,(见代码2),那这里查询工资最高的第2名到底应该是谁呢?这就不属于本博客(ROWNUM专题)讨论的范围了,因此下面仅仅提供代码和简单说明,更多内容见参考博客
  RANK()函数将值相同的记录返回相同的编号,但是相同编号的记录依然占据着初始的序号。当你查询工资最高的第3名时(见代码9),提示未选定行,而不是这一条记录 7566 JONES 2975。【代码8】:

SELECT EMPNO,ENAME,SAL
FROM (
        SELECT
                RANK() OVER(ORDER BY SAL DESC) NO,
                EMPNO,ENAME,SAL
        FROM EMP
)
WHERE NO=2;

  查询结果如下,【结果8】:

SQL> SELECT EMPNO,ENAME,SAL
  2  FROM (
  3          SELECT
  4                  RANK() OVER(ORDER BY SAL DESC) NO,
  5                  EMPNO,ENAME,SAL
  6          FROM EMP
  7  )
  8  WHERE NO=2;

     EMPNO ENAME             SAL
---------- ---------- ----------
      7788 SCOTT            3000
      7902 FORD             3000
6、查询工资最高的第3名员工

  查询工资排名第3名的员工,【代码9】:

SELECT EMPNO,ENAME,SAL
FROM (
        SELECT
                RANK() OVER(ORDER BY SAL DESC) NO,
                EMPNO,ENAME,SAL
        FROM EMP
)
WHERE NO=3;

  查询结果如下,【结果9】:

SQL> SELECT EMPNO,ENAME,SAL
  2  FROM (
  3          SELECT
  4                  RANK() OVER(ORDER BY SAL DESC) NO,
  5                  EMPNO,ENAME,SAL
  6          FROM EMP
  7  )
  8  WHERE NO=3;

未选定行

  RANK()DENSE_RANK()的其他参考:RANK()和DENSE_RANK()

重点

  ROWNUM是伪列,总是先有结果集才有ROWNUM的,因此它总是从1开始,如果你查询大于1的,它总是将条件置为FALSE,所以永远都查不到大于1的行,要想查询后面的行,必须要用嵌套查询,先进行一个排序,或者用别名。ROWNUM主要用于分页查询时使用。

最后

  以上是一个简单小结,想深入了解的可以去看看我附的别人的博客链接,个人认为他们写的挺好的。跳转到参考博客


  更新时间:2019年5月8日22:39:26

原文地址:https://www.cnblogs.com/wowpH/p/11060797.html