oracle rownum与order by

本文深入探讨了SQL中ROWNUM和ORDER BY的使用方法及其对查询性能的影响,通过实例展示了如何利用ROWNUM实现分页查询,并讨论了在不同场景下ROWNUM与ORDER BY结合使用的最佳实践,旨在提升查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为ROWNUM是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列 (强调:先要有结果集)。简单的说 rownum 是对符合条件结果的序列号。它总是从1开始排起的。这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。

另外:rowid 与 rownum 虽都被称为伪列,但它们的存在方式是不一样的,rowid 可以说是物理存在的,表示记录在表空间中的唯一位置ID,在DB中唯一。只要记录没被搬动过,rowid是不变的。rowid 相对于表来说又像表中的一般列,所以以 rowid 为条件就不会有 rownum那些情况发生。

1.rownum = n

如果希望找到第一条信息,可以使用rownum=1作为条件。

但是想找到表中第二条信息,使用rownum=2结果查不到数据。(注意不是报错,是没数据)

因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)  


2.rownum > n

如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum>n(n>1的自然数)这种条件依旧不成立,所以查不到记录 。

那如何才能找到第二行以后的记录?可以使用以下的子查询方法来解决。

注意子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。 

select * from(select rownum no ,FILE_ID,priority from index_file_info) where no>2; 


3.rownum < n

如果想找到第三条记录以前的记录,当使用rownum<3是能得到两条记录的。显然rownum对于rownum<n((n>1的自然数)的条件认为是成立的,所以可以找到记录。


4.n < rownum < m

例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。 

select * from(select rownum num, FILE_ID,priority from index_file_info where rownum<=3) where num>=2;


5.rownum 和 order by

Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。

select rownum, FILE_ID,priority from index_file_info order by file_id;

rownum FILE_ID priority

627 eoa_0_10_103.txt 10

628 eoa_0_10_120.txt 10

可以看出,rownum并不是按照FILE_ID列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rownum也是顺序分配的。为了解决这个问题,必须使用子查询 

 select rownum ,FILE_ID,priority from (select * from index_file_info order by FILE_ID); 

rownum FILE_ID priority

1 eoa_0_10_103.txt 10

2 eoa_0_10_120.txt 10

问题一:按某个字段排序,取前20条(分页)

 “select * from tabname where rownum < 20 order by name" 但却发现oracle却不能按自己的意愿来执行,而是先随便取20条记录,然后再 order by,后经咨询oracle,rownum确实就这样,想用的话,只能用子查询 来实现先排序,后  rownum,方法如下:

"select * from (select * fromtabname order by name) where  rownum<20",但这样一来,效率会较低很多。      只需在orderby 的字段上加主键或索引即可让oracle先按 该字段排序,然后rownum

如果排序列上有索引,则借助索引去查询数据,这样,读取出来的数据和rownum产生的序号是一种正常的对应关系,如语句一的结果(empno上有主键索引)。
  如果排序列上没有索引,则使用全表扫描的方式,依次从表中读取数据,读取完成后,最后进行排序,于是产生了类似语句二的结果(sal列上没有索引)。

select * from 
   (select rownum num, t.* from  

(select FILE_ID, priority from index_file_info order by FILE_ID) t) 

where num between 6 and 10;

当然,如果使用分析函数row_number就可以省略一层查询了,代码更简单点: 
      select * from 
   (select  row_number()  over  (order by FILE_ID) num, priority, FILE_ID  from index_file_info) 
   where num between 6 and 10;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值