ROWNUM is an Oracle pseudo column which numbers the rows in a result set.

SELECT rownum, table_name
FROM user_tables;
ROWNUM        TABLE_NAME                     
------------- -----------------
1 EMP
2 DEPT
3 BONUS
4 SALGRADE
5 DUMMY
5 rows selected

Here is a summary of how ROWNUM can be used.

LIMITING ROWS

ROWNUM can be used to limit the number of rows returned by a query in a similar way to LIMIT in Postgres and MySql, TOP in SQL Server and FETCH FIRST in DB2.

SELECT rownum, table_name
FROM user_tables
WHERE rownum <=3;
ROWNUM        TABLE_NAME                     
------------- -----------------
1 EMP
2 DEPT
3 BONUS
3 rows selected

ROWNUM WITH DML

The use of ROWNUM is not restricted to select statements. It can be used with DML statements that update the database too.

CREATE TABLE o AS
SELECT *
FROM all_objects
WHERE rownum <= 1000;
Table created
UPDATE o
SET object_id = rownum,
created = created + INTERVAL '1' MINUTE * rownum
WHERE rownum <= 100;
100 rows updated
DELETE FROM o
WHERE OWNER = 'SYS'
AND rownum = 1;
1 rows deleted

ROWNUM is particularly useful, when used in conjunction with the CONNECT BY LEVELclause, for creating arbitrary rows in the database. See the article ongenerating rows in Oraclefor more details.

OFFSETTING ROWS

Rows can also be skipped at the beginning of a result set using ROWNUM.

SELECT rnum, table_name
FROM
(SELECT rownum rnum, table_name
FROM user_tables)
WHERE rnum > 2;
RNUM     TABLE_NAME                     
-------- ----------------
3 SALGRADE
4 DUMMY
5 DEPT
3 rows selected

You will notice that an inline view has been introduced to transform the ROWNUMpseudo column into a 'real' column before we do the comparison.

It is tempting to write the above SQL as follows.

SELECT table_name
FROM user_tables
WHERE rownum > 2;
TABLE_NAME                     
------------------------------
0 rows selected

However, this query will always return zero rows, regardless of the number of rows in the table.

To explain this behaviour, we need to understand how Oracle processes ROWNUM. When assigning ROWNUM to a row, Oracle starts at 1 and only only increments the value when a row is selected; that is, when all conditions in the WHERE clause are met. Since our condition requires that ROWNUM is greater than 2, no rows are selected and ROWNUM is never incremented beyond 1.

The bottom line is that conditions such as the following will work as expected.

.. WHERE rownum = 1;

.. WHERE rownum <= 10;

While queries with these conditions will always return zero rows.

.. WHERE rownum = 2;

.. WHERE rownum > 10;

TOP-N QUERY

Typically, a top-n query sorts data into the required sequence and then limits the output to a subset of rows.

For example, suppose we wish to retrieve the top three earners from our employee table.

SELECT ename, sal
FROM (
SELECT ename, sal
FROM emp
ORDER BY sal DESC)
WHERE rownum <=3;
ENAME      SAL                    
---------- ---------
KING 5000
SCOTT 3000
FORD 3000
3 rows selected

The inline view (the inner select) sorts the rows and passes the result up to the outer select. The outer select then limits the output to three rows.

It may seem more natural to use the following SQL.

SELECT ename, sal
FROM emp
WHERE rownum <=3
ORDER BY sal DESC;
ENAME      SAL                    
---------- ----------------------
ALLEN 1600
WARD 1250
SMITH 800
3 rows selected

However, this does not give us the result we want because Oracle assigns theROWNUM values to the rows before it does the sort.

In this example, Oracle will retrieve three rows from the table, any three rows, and sort only these three rows. We really need Oracle to sort all the rows and then return the first three. The inline view will ensure that this will happen.

SORT PERFORMANCE

Limiting rows on a sorted result set using ROWNUM can also provide an added performance benefit. Rather than physically sorting all the rows to retrieve just the top few, Oracle maintains an array which contains just the highest or the lowest values (depending on whether we specified ASC or DESC in the ORDER BY clause). The size of the array will be the number of rows we wish to return. As rows are processed, only the highest (or lowest) values are retained in the array. All other rows are discarded.

PAGINATION

Next, we will see how ROWNUM is used to select a range of rows from within a result set. This is useful if we are to provide pagination on a web screen, for example.

Suppose we are paging through the employee table in name order and we wish to display rows six to ten inclusive.

SELECT rnum, ename, job
FROM
(SELECT /*+ FIRST_ROWS(10) */ rownum rnum, ename, job
FROM
(SELECT ename, job
FROM emp
ORDER BY ename)
WHERE rownum <= 10
)
WHERE rnum > 5;
RNUM     ENAME      JOB       
-------- ---------- ---------
6 JAMES CLERK
7 JONES MANAGER
8 KING PRESIDENT
9 MARTIN SALESMAN
10 MILLER CLERK
5 rows selected

We use nested inline views to retrieve and sort the data and then apply the range check using ROWNUM. We have split the upper and lower bound check, which allows Oracle to use COUNT(STOPKEY) in the execution plan when checking forROWNUM <= 10. This is a performance optimization which, along with the sorting optimization described earlier, will ensure that our query runs efficiently as the table grows.

The FIRST_ROWS(n) hint also tells Oracle to optimize the query so that the first n rows are returned as quickly as possible.

SUMMARY

ROWNUM provides a mechanism for returning a subset or range of rows from a query. It can be misleading at first if not properly understood but, once mastered, is invaluable for limiting result set output for pagination and top-n style queries.

For more information on ROWNUM, see Tom Kytes articleon OTN.

摘自:http://blog.lishman.com/2008/03/rownum.html

Using ROWNUM in Oracle的更多相关文章

  1. 使用rownum对oracle分页

    以Student表为例进行分页 建表及插入 -- 有表结构如下 create table STUDENT ( sno INTEGER, sname ), sage INTEGER ); -- 插入数据 ...

  2. 使用rownum对oracle分页【原】

    以Student表为例进行分页 建表及插入 -- 有表结构如下 create table STUDENT ( sno INTEGER, sname ), sage INTEGER ); -- 插入数据 ...

  3. 【Oracle】oracle中rownum的说明及使用技巧

    oracle中常用到ROWNUM,所以做一些本人对rownum的一些认识和使用技巧的记录,以便备查. 一.rownum的说明 rownum是oracle特有的一个关键字. (1)对于基表,在inser ...

  4. oracle rownum paging issues

    rownum是oracle预处理字段,默认标序是1,只有记录集已经满足条件后才会进行后续编号.由于第一条记录rownum默认是1,而你的条件是rownum>=6 对第一条记录比较它的rownum ...

  5. oracle中rownum和rowid的区别

    rownum和rowid的区别总括: rownum和rowid都是伪列,但是两者的根本是不同的. rownum是根据sql查询出的结果给每行分配一个逻辑编号,所以你的sql不同也就会导致最终rownu ...

  6. oracle 分页(rownum的理解) 以及 树节点的查询

    1:什么是rownum, rownum的生成, rownum相关的符号操作 Rownum是oracle生成结果集时得到的一个伪列, 按照读出行的顺序, 第一条rownum=1, 第二条=2. 对于 O ...

  7. Oracle中rownum的用法

    rownum是Oracle对查询结果进行顺序编号,第一行分配1,第二行2,以此类推.rownum不能以任何表的名称作为前缀. rownum这个伪字段可以用于控制返回的记录行数. 例如表:student ...

  8. Oracle的rownum原理

    Oracle中,按特定条件查询前N条记录,用个rownum就搞定了: SQL> select * from dept where rownum<3; 而对rownum用"> ...

  9. Oracle ROWNUM用法和分页查询总结(转)

    [转载] Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. Oracle分页查询格式(一):http://yangtingkun.itpub.net/post/468/100278 ...

随机推荐

  1. DOM commend

    var comment = document.createComment("commend content"); var elem = document.getElementByI ...

  2. Cmake编译成静态库

    To build OpenCV as static library you need to set BUILD_SHARED_LIBS flag to false/off: cmake -DBUILD ...

  3. NSIS检测操作系统x64还是x86的问题。

    想共同维护一个NSIS脚本文件的,不想搞两个版本的脚本文件了.开始想到了!if语句,没试过,不知道行不行得通.后来google了一下.可以用两个头文件搞定.参照下面链接 Reference: http ...

  4. Jquery回车键切换焦点方法(兼容各大浏览器)

    做项目时,客户要求能够用enter回车直接切换输入(焦点),当最后一个时候,直接提交信息. 第一想法就是,网上去copy一段代码直接用.但了百度.谷歌找了个遍,找到的代码80%以上都是一样的.有的代码 ...

  5. Codeforce 220 div2

    D 插入: 在当前指针位置sz处插入一个1,col[sz]记录插入的内容,sz++; 删除i: 找到第i个1的位置,赋为0; 于是转化为一个维护区间和的问题; trick: 如果是依次删除a[0],a ...

  6. Android apk获取系统权限

    Android在apk内部,即通过java代码来进行修改系统文件或者修改系统设置等等,这样需要获取系统权限. 通过直接配置apk运行在System进程内 1. 在应用程序的AndroidManifes ...

  7. mysql 主从复制配置步骤

    1.准备两台数据库环境,或者单台多实例环境,能否正常启动和登录. 2.配置my.cnf文件,主库配置log-bin和server-id参数,从库配置server-id,不能和主库及其他从库一样,一般不 ...

  8. c#利用VM_COPYDATA实现进程间通信

    c#进程间的通信方式很多种,只会这种,感觉比较简单.不懂原理,能用就行. 假设有两个程序:server(主进程),client(子进程) 1.server端: /*定义一个结构体,用来接收从子进程传过 ...

  9. sql 根据时间获取数据

    获取当月数据 MONTH(时间字段)=MONTH(GETDATE()) and year(时间字段)=year(GETDATE()) 计算两个时间差了多少分钟 DATEDIFF(mi,'7:00',c ...

  10. Android SDK离线安装

    Android SDK离线安装是本文要介绍的内容,主要是来了解并学习Android SDK安装的内容,具体关于Android SDK是如何离线安装的内容来看本文详解. Android开发环境,完整的说 ...