您的位置:首页 > 数据库 > Oracle

关于oracle的rownum分页问题

2013-06-30 00:05 267 查看
困扰了我好久,百度知道大神的回答非常精彩,前来与各位分享

我的提问:

select * from (select rownum as r,e.* from (select * from emp) e where rownum<=6) where r>=4;
select * from (select rownum ,e.* from (select * from emp) e where rownum<=6) where rownum>=4;
请问为什么第一个语句就能查询出结果,第二个就查不到,没什么区别嘛
select rownum ,e.* from (select * from emp) e where rownum>=1
select rownum ,e.* from (select * from emp) e where rownum>1
这两个也是第一个能查出结果,第二个查不出
select * from (select rownum as r,e.* from (select * from emp) e where rownum<=6) where r>=4;
select * from (select rownum as r,e.* from (select * from emp) e where rownum>=4) where r<=6;
这两个也是第一个能查出,第二个查不出,求解释啊。。。。

oracle版本为11g,plsql工具


大神回答:

你对分页查询的理解不到位,当初我也很困扰这问题,直到我看到一段话,复制给你吧。

对于rownum的理解

1.rownum和orderby的排序先后问题。rownum是根据块的取值顺序来的,order by是select做完之后才进行排序的,所以先有rownum,再有order by。 也就是说如果你想按照某一列的顺序取一段范围,如果直接取rownum<n,这样是不准确的,必须先用order by对该列排序,再在第二层用rownum来取。

2.rownum总是从1开始统计的,不能抛开“rownum=1”这个潜在的重要条件而单独存在。

根据上述观点,我们可以很好的解析为何无法选出rownum>10的原因:

☆rownum总是从rownum=1开始排列,☆ (好好的理解左边这句话) 而筛选的结果是要求rownum>10,当选出来的结果不大于10,于是被删去;第二个rownum出来值又是1,于是不满足条件又被删去........

☆因为前面出来的rownum都被删了,所以到了第N个rownum他还是从=1开始取值,仍然不满足>10这个条件,因此还是被删了,所以到了最后,得到的就是空了☆

再比如:rownum!=10,rownum会选取从1到9的值,到了第十个值,因为不满足“!=10”这个条件而被删去,第十一个值出来时仍然被标记为rownum=10,因为不满足条件又被删去... 所以“rownum!=10”实际上与“rownum<10”结果是相同的

当我们要查询rownum>10的部分时,必须先将所有的rownum选出来,生成一列,但此时注意要点:rownum不能以任何基表的名称作为其前缀(即:a.rownum是不允许的),所以要对其改用别名。

上面那段话直接解释了你的第二个问题,为什么那里用“>”查询不出任何东西,因为你忽略掉了rownum=1这个必要条件。

现在来解释你的第一个问题,第一个问题的第二个语句,你没有对前一次的rownum用别名,而你最后的那个rownum>=4很明显是取的外层语句产生的rownum而不是之前内括号中的rownum列了,所以你取>=4,又忽略了必须=1这个条件,因此又是什么都没有

第三个问题的第二个语句同样的,直接>=4,仍然忽略了=1这个必要条件,所以也是空的。(第三个问题的第二个语句,内层就直接是空了,不信你试试,呵呵)

如果你还是不明白的话,综合来说就是3点

首先把你要选的按某列排列(通常有这个要求,rownum是根据块的顺序,而不一定是按照你所设定的某列的顺序得出结果的)eg: select * from table_a order by id

把第一步筛选出的选定出最大范围(即把rownum=1这个条件用进去),对rownum使用别名 select a.rownum as rn, a.* from (第一步的那个语句) a where rownum<m;

第二步已经划定了最大范围,再在这个最大范围里面取你所要的范围 select b.* from (第二步的语句) b where b.rn>=n (注意这里必须用b.rn而不是rownum)

这样你就取到n和m之间的那段值了。

关于分页查询的语句,推荐大师的一篇围脖

百(|和谐|)度搜:yangtingkun分页查询 可以搜到大师的一堆围脖,讲的很深入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: