Oracle的rownum原理
Oracle中,按特定条件查询前N条记录,用个rownum就搞定了:
SQL> select * from dept where rownum<3;
而对rownum用">",会失败:
SQL> select * from dept where rownum>3;
Oracle中rownum背后的机制:
1. Oracle执行SQL,得到第一行,rownum=1;
2. 判断得到的这一行是否满足条件。如果满足条件,返回此行,rownum=1;如果不满足条件,丢弃此行,继续读取下一行。
3. 读取下一行(如果上一步骤中找到满足条件的行),若满足条件,则rownum+1;否则rownum保持不变。
4. 重复3的动作,直到fetch完表中的数据。
了解了原理,就知道rownum>3不会成功,因为在第2步的时候查询出的行已经被丢弃,第3步查出来的rownum仍然是1,这样永远也不会成功。同样道理,rownum如果单独用=,也只有在rownum=1时才有用。
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。
举例说明:
SQL> select * from dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
(1) rownum 对于等于某值的查询条件
如果希望找到部门表中第一条部门的信息,可以使用rownum=1作为条件。但是想找到部门表中第二条部门的信息,使用rownum=2结果查不到数据。因为rownum都是从1开始,但是1以上的自然数在rownum做等于判断是时认为都是false条件,所以无法查到rownum = n(n>1的自然数)。
SQL> select rownum,deptno,dname from dept where rownum=1;(可以用在限制返回记录条数的地方,保证不出错,如:隐式游标)
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
SQL> select rownum,deptno,dname from dept where rownum=2;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
(2) rownum对于大于某值的查询条件
如果想找到从第二行记录以后的记录,当使用rownum>2是查不出记录的,原因是由于rownum是一个总是从1开始的伪列,Oracle 认为rownum> n(n>1的自然数)这种条件依旧不成立,所以查不到记录。
SQL> select * from dept where rownum>3;
未选定行
那如何才能找到第二行以后的记录?可以使用以下的子查询方法来解决。
注意:子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
SQL> select * from (select rownum rn,deptno,dname from dept) where rn>2;
RN DEPTNO DNAME
---------- ---------- --------------
30 SALES CHICAGO
40 OPERATIONS BOSTON
(3) rownum对于小于某值的查询条件
如果想找到第三条记录及以前的记录,当使用rownum<=3是能得到两条记录的。显然rownum对于rownum<=n((n>1的自然数)的条件认为是成立的,所以可以找到记录。
SQL> select * from dept where rownum<=3;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
(4) rownum对于区间查询条件
从上可以看出rownum对小于某值的查询条件是为true的,rownum对于大于某值的查询条件直接认为是false的。那就必须使用子查询。
例如要查询rownum在第二行到第三行之间的数据,包括第二行和第三行数据,那么我们只能写以下语句,先让它返回小于等于三的记录行,然后在主查询中判断新的rownum的别名列大于等于二的记录行。但是这样的操作会在大数据集中影响速度。
SQL> select * from (select rownum rn,deptno,dname from dept where rownum<=3) where rn>=2;
RN DEPTNO DNAME
---------- ---------- --------------
2 20 RESEARCH
3 30 SALES
(5) rownum和排序
Oracle中的rownum的是在取数据的时候产生的序号,所以想对指定排序的数据去指定的rowmun行数据就必须注意了。
SQL> select rownum,deptno,dname from dept order by dname;
ROWNUM DEPTNO DNAME
---------- ---------- --------------
1 10 ACCOUNTING
4 40 OPERATIONS
2 20 RESEARCH
3 30 SALES
可以看出,rownum并不是按照dname列来生成的序号。系统是按照记录插入时的顺序给记录排的号,rowid也是顺序分配的。为了解决这个问题,必须使用子查询。
SQL> select rownum,deptno,dname from(select * from dept order by dname);
ROWNUM DEPTNO DNAME
---------- ---------- --------------
1 10 ACCOUNTING
2 40 OPERATIONS
3 20 RESEARCH
4 30 SALES
这样就成了按dname排序,并且用rownum标出正确序号(有小到大)。
Oracle的rownum原理的更多相关文章
- Oracle中rownum原理介绍
rownum原理如下:1.执行查询操作2.将第一行的row num置为13.将得到的行的row num与条件相比较,如果不匹配,则抛弃行,如果匹配,则返回行4.oracle获取下一行,然后将rownu ...
- Oracle的rownum原理和使用
整理和学习了一下网上高手关于rownum的帖子: 参考资料: http://tech.ddvip.com/2008-10/122490439383296.html 和 http://tenn.jav ...
- Oracle的rownum原理和使用(整理几个达人的帖子)
整理和学习了一下网上高手关于rownum的帖子: 参考资料: http://tech.ddvip.com/2008-10/122490439383296.html 和 http://tenn.jav ...
- oracle中rownum和row_number()
row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内 ...
- ORACLE 中rownum和row_number()的使用区别(可指定取sql结果集的第几个数据)
这篇文章主要介绍了oracle中rownum和row_number()的使用方法以及区别和联系,十分的详细,有需要的小伙伴可以参考下. row_number()over(partition by ...
- oracle关于rownum的使用【oracle】
转自:https://blog.csdn.net/qiuzhi__ke/article/details/78892822 关于rownum是怎么产生的(网上有不少的文章,下面是摘录): rownum是 ...
- ORACLE 中ROWNUM用法总结(转)
ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...
- 【Oracle】oracle中rownum的说明及使用技巧
oracle中常用到ROWNUM,所以做一些本人对rownum的一些认识和使用技巧的记录,以便备查. 一.rownum的说明 rownum是oracle特有的一个关键字. (1)对于基表,在inser ...
- oracle之rownum(伪列)
整理和学习了一下网上高手关于rownum的帖子: 参考资料: http://tech.ddvip.com/2008-10/122490439383296.html 和 http://tenn.jav ...
随机推荐
- iOS之Xcode8 Auto Layout新特性
目录 1.Incrementally Adopting Auto Layout 2.Design and Runtime Constraints 3.NSGridView 4.Layout Feedb ...
- spring-boot配置外部静态资源的方法
import java.io.File; import javax.servlet.Servlet; import lombok.extern.slf4j.Slf4j; import org.spri ...
- TensorFlow学习之运行label_image实例
前段时间,搞了搞编译label_image中cc的实例,最后终于搞定...但想在IDE中编译还没成功,继续摸索中. 现分享一下,探究过程,欢迎叨扰,交流. 个人地址:http://home.cnblo ...
- 从医生看病和快餐店点餐理解Node.js的事件驱动
第一个例子是关于医生看病. 在美国去看医生,需要填写大量表格,比如保险.个人信息之类,传统的基于线程的系统(thread-based system),接待员叫到你,你需要在前台填写完成这些表格,你站着 ...
- java-MySQL存储过程
import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import ...
- [转]C# 获取系统文件图标
//获取文件的图标 this.Icon = GetFileIcon(@"c:\gdiplus.dll"); //获取文件夹图标 this.Icon = GetDirectoryIc ...
- PHP之自定义会话控制---使用文件处理
前三篇简单的总结了下会话控制和文件操作,这一篇说说会话控制的自定义处理方式.既然知道了文件的基本读写,而且在会话控制中,也有人提到,session数据可以保存到缓存或数据库中,实际上当然不会是直接利用 ...
- 原生javascript焦点轮播图
刚刚学会,写了一个轮播图效果,不过bug蛮多,请高手指点一下,谢谢 <!DOCTYPE html> <html> <head> <meta charset=& ...
- Android实现贪吃蛇游戏
[绥江一百]http://www.sj100.net 欢迎,进入绥江一百感谢点击[我的小网站,请大家多 ...
- Learn Python The Hard Way学习笔记001
今天搜索了一下raw_input() 和 input()的区别,引用下原文部分内容 两个函数均能接收 字符串 ,但 raw_input() 直接读取控制台的输入(任何类型的输入它都可以接收).而对于 ...