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 ...
随机推荐
- git merge branches
git clone url #克隆新的版本库 git init git pull repo_name #有关联的远程库,抽取并和本地合并 git fetch remote_repo_name #抽取并 ...
- linux -cp/mv
cp 复制 -r文件夹 -f强制没有提示 mv 移动改名 mv test.py temp/test2.py移动(后面只加路径就是移动.路径+文件名就是移动+改名) 执行mv一般会执行 mv -i交互 ...
- redis中5种数据结构的使用
一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 ...
- oracle中的sql%rowcount
sql%rowcount用于记录修改的条数,就如你在sqlplus下执行delete from之后提示已删除xx行一样,这个参数必须要在一个修改语句和commit之间放置,否则你就得不到正确的修改行数 ...
- [改善Java代码]三元操作符的类型务必一致
建议三: 三元操作符是if-else的简化写法,在项目中使用它的地方很多,也非常好用,但是好用又简单的东西并不表示就可以随便用,我们来看看下面这段代码: public class Client { p ...
- hdu 2844 多重背包+单调队列优化
思路:把价值看做体积,而价值的大小还是其本身,那么只需判断1-m中的每个状态最大是否为自己,是就+1: #include<iostream> #include<algorithm&g ...
- Android中定义接口的方法
1.接口方法用于回调(这里定义接口是为了使用其接口方法): public interface ICallback { public void func(); } public class Caller ...
- css3 背景记
css3 背景 css背景主要包括五个属性: background-color background-color:transparent || <color> 用来设置元素的背景颜色,默认 ...
- Java Concurrency - java.util.concurrent API Class Diagram
摘自: www.uml-diagrams.org Here we provide several UML class diagrams for the Java™ 7 java.util.concur ...
- hive 未初始化元数据库报错
启动hive-metastore和hive-server2 用beeline连接hive报错 [root@node04 hive]# beeline Beeline version 0.13.1-cd ...