求oracle分页查询语句方案oracle的分页语句我已经知道
在网上查了一下,大概都是这些:

SELECT /*+ FIRST_ROWS */ * FROM 
(
SELECT A.*, ROWNUM RN 
FROM (SELECT * FROM TABLE_NAME) A --不排序
WHERE ROWNUM <= 40
)
WHERE RN >= 21;SELECT /*+ FIRST_ROWS */ *
FROM (SELECT a.*, row_number() over(ORDER BY 1) rn--假排序,速度同上
FROM t1 a)
WHERE rn BETWEEN 21 AND 40;SELECT *
FROM (SELECT a.*, row_number() over(ORDER BY c1) rn --真实排序,无法比较速度
FROM t1 a)
WHERE rn BETWEEN 21 AND 40;我想问的是:你怎么保证你下一次查询时,结果集还是按照原来查询的顺序排列的呢?
如果不能保证,那你在查询下一页内容就是不是对应上次查询的下一页内容,比如:第一次查询,结果集是这样的:
1,a
2,b
3,c
4,d
5,f
6,e
7,f
8,g
9,h
10,i如果用上述语句:假如结果集而是:
1,a
2,b
3,c
4,d
5,f那我想查询下一页内容,应该是:
6,e
7,f
8,g
9,h
10,i你怎么保证一定就是这5条呢?
它不一定还是按照第一次查询的顺序排列的啊,结果集可能是:
1,h
2,g
3,c
4,a
5,p
这个我已经实际验证过了,真的不是第一查询的顺序。
所以才会问这个问题,不知各位前辈怎么样用oracle做分页查询的?
希望赐教。

解决方案 »

  1.   

    一般来说,用的都是第一种
    SELECT /*+ FIRST_ROWS */ * FROM  
    (
    SELECT A.*, ROWNUM RN  
    FROM (SELECT * FROM TABLE_NAME) A --不排序
    WHERE ROWNUM <= 40
    )
    WHERE RN >= 21;按照ROWNUM来分页的话,的确有可能出现排序不一致,可能性的大小取决你表的数据被更新,删除的频度,在真实应用里的变化一般可以忽略,由于他速度最快,一般都用这个如果一定要严格的排序的话,一般在第一种的语句上做变化,如下
    SELECT /*+ FIRST_ROWS */ * FROM  
    (
    SELECT A.*, ROWNUM RN  
    FROM (SELECT * FROM TABLE_NAME ORDER BY ..) A --排序
    WHERE ROWNUM <= 40
    )
    WHERE RN >= 21;第三种的话,使用分析函数,太耗资源了,不建议这么用,尤其大数据量的前提下
      

  2.   

    刚才我又做了些实验,大家看下结果:select b.* from 
    (
    select t.*,rownum rr from v_view_forta t 
    ) b 
    where b.rr  between 5 and 8 
    order by b.rr--1,13 表中group字段 
    020801
    020801
    020801
    0201
    01050310
    021201
    021201
    021201
    03060306
    0212
    021301-- 11,13 表中group字段 ,正确
    0306
    0212
    021301
    -- 5,8 表中group字段 正确
    0105 
    0310
    021201
    021201
    select k.*,rownum rr from v_view_forta k 
    where rownum between 2 and 6
    -- 1,10
    0101
    0101
    0104
    0104
    01050105
    0110
    011002
    011002
    011002-- 2,6 结果集为空!!!-- 这样写结果同上
    /*select g.*,rownum rr from v_view_forta g 
    where rownum>=3 and rownum<=10*/
    select * from
    (
    select d.*,rownum rr from v_view_forta d 
    ) p 
    where p.rr>=2 and p.rr<=7--  1,10
    020801
    020801
    020801
    0201
    01050310
    021201
    021201
    021201
    0306
     
    -- 2,7  正确
    020801
    020801
    0201
    0105
    0310
    021201/*结论:使用rownum做分页查询,必须将rownum放在子查询内!否则不起作用!!!*/
    这是我得出的结论,不知大家有何见解,集思广益,希望大家献计献策,感激不尽!
      

  3.   

    /*结论:使用rownum做分页查询,必须将rownum放在子查询内!否则不起作用!!!*/结论明显是错误的,ROWNUM的优先级高于ORDER BY ,如果要按一定顺序排列的话,必然要ORDER BY 放在子查询里,然后再取ROWNUM
      

  4.   

    ROWNUM不是查询之后生成的。它是表中的一个伪列。每张表都设置了类似于ROWNUM这样的伪列。rownum的赋值时间:
    在数据库解析完查询语句之后,并且在查询语句做任何的排序或者聚合之前,ROWNUM被赋值,就是在查询的时候已经被赋值了 所以在这个基础上取的数据 看出来的效果就是数据库默认的排序效果
    假设表名tb1  表字段id,no  取分组排序后的5-10条数据
     select *
    from ( 
            select a.*,
                   row_number() over(partition by a.no order by a.id) rn 
            from tb1 a
          )t1 
    where rn > 4 and rn <10
    这个和rownum效果差不多  必须要在子查询里面进行排序后 才能在外层取的想要的排序后的数据
      

  5.   

    如果我的结论是错误的,那怎么解释:select g.*,rownum rr from v_view_forta g  
    where rownum>=3 and rownum<=10查到的是空?