今天学习Oracle的时候遇到了rownum,并没有完全搞清楚,然后将查询条件中的rownum <= 10修改成了 rownum > 10,想查询出第十条记录之后的所有记录,结果什么都没查出来,一头雾水,后来百度了几个博客,终于搞明白了,做个笔记记录一下。
1、rownum运行原理
要想在使用的时候没有疑惑,必须先搞清楚它的运行原理,它到底做了哪些工作。
rownum是Oracle为查询结果集添加的一个伪列,之所以是伪列是因为它不属于查询表的一个列,而是Oracle在查询得到结果集之后添加的一个列。通俗一点讲就是为查询的记录添加一个序列号,这个序列号从1开始,然后递增,所以查询的结果中不能没有1这个序号。但这个序号存在的前提是查询的结果集已经存在了,不能在结果集之前有这个伪列。因此,如果按照以下查询,是没有结果的:
select * from student where rownum > 10;
当查询到一条数据后,rownum值为1,不符合条件,结果被丢掉,继续查询第二天数据,rownum又从1开始计数(rownum永远是从1开始递增),所以,这样把整个表遍历了一遍,但是一条数据都没筛选出来,因为rownum永远为1,永远不符合条件。如果是以下语句,结果就正确:
select * from student where rownum <= 10;(筛选前十条数据)
rownum开始值为1,符合条件,然后rownum递增到2,也符合条件……最后rownum递增到11,不符合条件了,所以查询出的就是前十条数据,正确。
还有以下几个例子,根据以上解释,这些结果也就不奇怪了:
select * from student where rownum > 0;(整个表的数据)
select * from student where rownum > 1;(一条数据都没有)
select * from student where rownum >= 1;(整个表的数据)
select * from student where rownum <= 1;(第一条数据)
2、嵌套使用rownum
按照以上所述,我们目前没有办法获取第十条之后的数据,但如果我们就是想获取该怎么办呢?这里就用到了嵌套select,如下:
select * from
(
select
rownum my_rownum, s.*
from
student s
)
where
my_rownum > 10;
该查询先执行了子查询,子查询的结果集中rownum编号都已经生产了,然后再筛选第十条之后的数据就可以成功了。
3、利用rownum来进行分页操作
(这部分内容还么有研究,正在学习中……)