`

解析oracle的rownum

阅读更多
在使用oracle的rownum实现分页显示的时候,对rownum做了进一步的分析和研究。现归纳如下
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀(此处的前缀是指:rownum不能作为任何表的别名)。

例如表:student(学生)表,表结构为:
ID       char(6)      --学号
name    VARCHAR2(10)   --姓名

create table student (ID char(6), name VARCHAR2(100));

insert into sale values('200001',‘张一’);
insert into sale values('200002',‘王二’);
insert into sale values('200003',‘李三’);
insert into sale values('200004',‘赵四’);
commit;


(1) rownum 对于等于某值的查询条件
如果希望找到学生表中第一条学生的信息,可以使用rownum=1作为条件。但是想找到学生表中第二条学生的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。
SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)

(2)rownum对于大于某值的查询条件
   如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录
SQL> select rownum,id,name from student where rownum >2;
ROWNUM ID     NAME
---------- ------ ---------------------------------------------------
那如何才能找到第二行以后的记录呀。可以使用以下的子查询方法来解决。
注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是
某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
SQL>select * from(select rownum no ,id,name from student) where no>2;
       NO ID     NAME
---------- ------ ---------------------------------------------------
        3 200003 李三
         4 200004 赵四
SQL> select * from(select rownum,id,name from student)where rownum>2;
    ROWNUM ID     NAME
  
    以上查询没有对rownum做别名,所以查询不到记录!

(3)rownum 对于小于某值的查询条件
如果想找到第三条记录以前的记录,当使用rownum<3是能得到两条记录的。
显然rownum对于rownum<n((n>1的自然数)的条件认为是成立的,所以可以找到记录SQL> select rownum,id,name from student where rownum <3;
   ROWNUM     ID       NAME
---------   ----      -----
     1       200001    张一
      2       200002    王二
综上几种情况,可能有时候需要查询rownum在某区间的数据,那怎么办呀
从上可以看出rownum对小于某值的查询条件是人为true的,rownum对于大于某值的查询条件直接认为是false的,但是可以间接的让它转为认为是true的。那就必须使用子查询。
例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,
先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。

SQL> select * from (select rownum no,id,name from student where rownum<=3 ) where no >=2;
        NO   ID       NAME
        --- ----    ------
         2   200002   王二
          3   200003   李三



以下部分,转自:http://www.cnblogs.com/Ronger/archive/2012/05/14/2498971.html

SELECT * FROM ( SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A WHERE ROWNUM <= 40 ) WHERE RN >= 21

上面给出的这个分页查询语句,在大多数情况拥有较高的效率。分页的目的就是控制输出结果集大小,将结果尽快的返回。在上面的分页查询语句中,这种考虑主要体现在WHERE ROWNUM <= 40这句上。

选择第21到40条记录存在两种方法,一种是上面例子中展示的在查询的第二层通过ROWNUM <= 40来控制最大值,在查询的最外层控制最小值。而另一种方式是去掉查询第二层的WHERE ROWNUM <= 40语句,在查询的最外层控制分页的最小值和最大值。这是,查询语句如下:
SELECT * FROM ( SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A ) WHERE RN BETWEEN 21 AND 40
对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。



这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。



而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)。因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。












分享到:
评论

相关推荐

    oracle的rownum深入解析

    本人最近在使用oracle的rownum实现分页显示的时候,对rownum做了进一步的分析和研究。现归纳如下,希望能给大家带来收获。 对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第...

    解析rownum

    本人最近在使用oracle的rownum实现分页显示的时候,对rownum做了进一步的分析和研究。现归纳如下,希望能给大家带来收获。

    Python调用SQLPlus来操作和解析Oracle数据库的方法

    先来看一个简单的利用python调用sqlplus来输出结果的例子: import os import sys from subprocess import Popen, PIPE ... where rownum&lt;=10; proc = Popen([sqlplus, -S, /, as, sysdba], stdout=PIPE, stdin=

    oracle查看会话锁定的所有对象代码分享

    代码如下:select session_id sid, owner, name, type, mode_held... 您可能感兴趣的文章:ORACLE 查询被锁住的对象,并结束其会话的方法解析Oracle数据库中的对象集合schemaORACLE 常用的SQL语法和数据对象Oracle使用PL/

    个人开发中遇到常见问题及解决办法(吐血总结)

    11 解析oracle的rownum 12 ava web项目中开放一个webservice接口实例 13 js方式实现 系统时间显示 14 js 按Enter健实现搜索 15 多选框批量删除 16 js实现单选全选 17 数据库表数据被误删之后的恢复

    Oracle 两个逗号分割的字符串,获取交集、差集(sql实现过程解析)

    Oracle数据库的两个字段值为逗号分割的字符串,例如:字段A值为“1,2,3,5”,字段B为“2”。 想获取两个字段的交集(相同值)2,获取两个字段的差集(差异值)1,3,5。 一、最终实现的sql语句 1、获取交集(相同值)...

    Oracle创建视图(View)

    c.ROWNUM伪列。 d.基表中未在视图中选择的其他列定义为非空且无默认值。 视图可用于保持数据库的完整性,但作用有限。 通过视图执行引用完整性约束可在数据库级执行约束。 WITH CHECK OPTION 子句限定: 通过...

    AppFramework_V1.0_New

    众所周知Oracle提供了ROWNUM实现数据数据库内分页功能,若要利用这一特性,就要在SQL模板里直接硬编码这些特殊语法,这必然导致大量的移植工作。 &lt;br&gt;第八、缺少代码生成和检查工具。程序里的变量名与Sql模板里的...

    AppFramework_V1.0

    众所周知Oracle提供了ROWNUM实现数据数据库内分页功能,若要利用这一特性,就要在SQL模板里直接硬编码这些特殊语法,这必然导致大量的移植工作。 &lt;br&gt;第八、缺少代码生成和检查工具。程序里的变量名与Sql模板里的...

    AppFramework数据库访问组件_代码生成插件_V1.1.rar

    众所周知Oracle提供了ROWNUM实现数据数据库内分页功能,若要利用这一特性,就要在SQL模板里直接硬编码这些特殊语法,这必然导致大量的移植工作。 &lt;br&gt;第八、缺少代码生成和检查工具。程序里的变量名与Sql模板里的...

Global site tag (gtag.js) - Google Analytics