1>:oracle中帶排序的分頁sql,至少包含三層,若無order by可以兩層,通用模板為(hibernate也是采用這種方法):
select temp2.* from(
select rownum num,temp1.* from(
SQL查詢
) temp1 where rownum<=?
)temp2 where temp2.num>?
如果是第一頁的分頁,可以簡化為兩層:
select * from(
SQL查詢
) where rownum <=?
2>:有些特性需要注意:
a:最內層的sql查詢中的order by項一定要保證記錄的唯一性,否則,若排序字段有重復記錄,則分頁查詢后,翻頁后數據會出現重復和缺少,因為oracle沒有默認排序一說,mysql的會按主鍵自然排序(?待確認),導致兩次分頁查詢的order by結果不一致,哎,這樣查詢時非冪等的。
b:rownum是個很蛋疼的偽列,它的對滿足查詢條件(不包括“含有rownum的查詢條件”和“排序條件”)的結果集的順序記錄,并且在生成結果集時逐一遞增,也就是發現對滿足查詢條件(不包括“含有rownum的查詢條件”和“排序條件”) 的第一條記錄,rownum附加為記錄上并賦值為(當前結果集的總數+1)1,然后若有rownum查詢條件,則使用rownum查詢條件來判斷,若符合則繼續查詢,否則舍棄記錄,然后接著查詢,以此推之,那么rownum一定從1開始,所以對<、<=可以很好支持,對!=可以像<一樣詭異支持,對其他的=、>、>=、between...and不為1的不支持了。
c:上面說rownum的賦值是在orderby前面的,所以若要利用好orderby,就必須使用子查詢,將orderby語句放在內層無rownum的語句中。