对oracle 中rownum 的理解

在Oracle中,要按特定条件查询前N条记录,用个rownum就搞定了。
select * from emp where rownum <= 5
而且书上也告诫,不能对rownum用">",只能使用"<=","<","!=",这也就意味着,如果你想用
select * from emp where rownum > 5
则是失败的。要知道为什么会失败,则需要了解rownum背后的机制:
1 Oracle executes your query.

2 Oracle fetches the first row and calls it row number 1.

3 Have we gotten past row number meets the criteria? If no, then Oracle discards the row, If yes, then Oracle return the row.

4 Oracle fetches the next row and advances the row number (to 2, and then to 3, and then to 4, and so forth).

5 Go to step 3.

了解了原理,就知道rownum>不会成功,因为在第三步的时候查询出的行已经被丢弃,第四步查出来的rownum仍然是1,这样永远也不会成功。

同样道理,rownum如果单独用=,也只有在rownum=1时才有用。

对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。

     rownum是伪劣,该列只存在于查询结果集中,并且结果集中rownum没有1就不会有2。

     当我们在执行select * from student where rownum!=5 时,oracle会给结果集加上rownum这一伪列,然后根据rownum!=5这个条件开始过滤,当遇到rownum!=5为false时,过滤会终止,将前面符合条件的记录返回给用户。

实现分页:

欢迎纠正

如何实现分页提取记录
方法1:oracle的ROWNUM伪列返回查询的行序号。
  例如要查询表的前10条记录,可以使用
  select * from tablename where ROWNUM<=10
  但是要返回第11-第20条记录,尝试以下的语句
  select * from tablename where ROWNUM<=20 and ROWNUM>=11;
  这个人报错。返回0条记录。因为ROWNUM是伪列,不能用>=条件
  使用以下方法可以查询第11-第20条记录
  select * from
  (select ROWNUM rn ,t.* from tablename t where ROWNUM<=20) where rn>=11;
方法2:使用分析函数ROW_NUMBER实现分页
  select * from (select ROW_NUMBER() OVER (ORDER BY id) rn,t.* from tablename t) 
    where rn between 11 and 20;
方法3:使用集合运算MINUS实现分页
  select * from tablename where ROWNUM<=20 MINUS
  select * from tablename where ROWNUM<11;
点评:方法1在查找前几页时速度很快。但在数据量很大时,最后几页速度比较慢。
方法2查询效率比较稳定,是推荐使用的方法。
方法3只适合查询结果在200行以内的情况,记录数很多时会导致oracle错误,需谨慎使用。

猜你喜欢

转载自slikel.iteye.com/blog/1637634
今日推荐