感觉有点问题,下面这个语句排序还是没有问题select rownum rownum_,TRAN_SN from history order by TRAN_SN DESC
如果是先生成rowNum再排序的话应该是下面结果rownum_ TRAN_SN
4 10002 9993 9981 992
但我数据库里实验后是:
rownum_ TRAN_SN
1 10002 9993 9984 992
根本没出现rownum的问题...如果成立 那么 分页是不是两层就可以 select * from (select rownum rownum_,TRAN_SN from history order by TRAN_SN DESC where rownum_<20) where rownum_>10呢?????????
如果是先生成rowNum再排序的话应该是下面结果rownum_ TRAN_SN
4 10002 9993 9981 992
但我数据库里实验后是:
rownum_ TRAN_SN
1 10002 9993 9984 992
根本没出现rownum的问题...如果成立 那么 分页是不是两层就可以 select * from (select rownum rownum_,TRAN_SN from history order by TRAN_SN DESC where rownum_<20) where rownum_>10呢?????????
明显的例子是你在检索条件中加上rownum < 10,你会发现检索结果中可能并没有出现你想要的东西
但我测试了下select rownum rownum_,TRAN_SN from history where rownum<2 order by TRAN_SN DESC
如果按假设出现的结果应该是只取两条排序,但我好像还是能得到正确结果!依然是得到如下rownum_ TRAN_SN
1 10002 999
如果按假设应该可能得到如下结果rownum_ TRAN_SN
1 9992 998
进行的排序,它会先找出最大的然后生成rownum
如果按照说的,是先rownum 然后order by那肯定是不一样的。
引出·······为什么会需要3层嵌套来分页。
楼主这个问题好啊,我也迷茫了,我也是一直认为是三层分页
今天试了一下scott@IPNET> select empno from emp; EMPNO
----------
7369
7499
7521
7566
7654
7698
7782
7788
7839
7844
7876
7900
7902
7934已选择14行。scott@IPNET> select rownum , empno from emp where rownum<3; ROWNUM EMPNO
---------- ----------
1 7369
2 7499scott@IPNET> select rownum , empno from emp where rownum<3 order by empno desc; ROWNUM EMPNO
---------- ----------
1 7934
2 7902
这个查询不加order by肯定是按照唯一索引升序排列的,所以前两条肯定是最小的两条,这是可预知的,所以最后一条语句如果先判断rownum再排序,肯定是对最小的两条排序,而不是结果得到的最大的两条数据用的是oracle 10g进行的查询
优先级是:where -> order by -> rownum2.正确希望对你有所帮助,记得给分!
也就是在查询出来的结果集之外又加了一列,这一列就是给结果集各行安排的一个序号而己。
这时在where rownum>10也就是按序号取相当的子结果集。
所以rownum是最后的最后才执行的。
语句一:select rownum,empno,sal from emp order by empno;
ROWNUM EMPNO SAL
---------- ---------- ----------
1 7369 800
2 7499 1600
3 7521 1250
4 7566 2975
5 7654 1250
6 7698 2850
7 7782 2450
8 7788 3000
……
语句二:select rownum,empno,sal from emp order by sal;
ROWNUM EMPNO SAL
---------- ---------- ----------
1 7369 800
12 7900 950
11 7876 1100
3 7521 1250
5 7654 1250
14 7934 1300
10 7844 1500
2 7499 1600
……
同样的两个语句,执行结果中的rownum伪列的值却大相径庭,这是什么原因呢?
其实这都是ORACLE内部的查询优化器和索引搞的鬼!
rownum伪列产生的序号是按照数据被查询出来的顺序添加上去的,第一条是1,第二条是2,依次加1。
当将一条语句交给查询优化器处理时:
如果排序列上有索引,则借助索引去查询数据,这样,读取出来的数据和rownum产生的序号是一种正常的对应关系,如语句一的结果(empno上有主键索引)。
如果排序列上没有索引,则使用全表扫描的方式,依次从表中读取数据,读取完成后,最后进行排序,于是产生了类似语句二的结果(sal列上没有索引)。
正是由于排序列上不一定有索引,所以在ORACLE中使用rownum伪列分页时,需要多加一层查询,以保证rownum序号的连续性。
语句三:select rownum,t.* from
(select empno,sal from emp order by sal) t;
ROWNUM EMPNO SAL
---------- ---------- ----------
1 7369 800
2 7900 950
3 7876 1100
4 7521 1250
5 7654 1250
6 7934 1300
7 7844 1500
8 7499 1600
……
这个结果还满意吧
分页:在外面再加上一层查询。
select * from
(select rownum num,t.* from
(select empno,sal from emp order by sal) t)
where num between 6 and 10;
当然,如果使用分析函数row_number就可以省略一层查询了,代码更简单点:
select * from
(select row_number() over (order by sal) num,empno,sal from emp)
where num between 6 and 10;