程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> [Oracle]ROWNUM和分頁

[Oracle]ROWNUM和分頁

編輯:Oracle教程

rownum是oracle的一個偽劣,它的順序根據從表中獲取記錄的順序遞增,這裡要注意的是:由於記錄在表中是無序存放的,因此你無法通過簡單的rownum和order by的組合獲得類似TOP N的結果。

我們的測試數據如下:

 select * from test;

        ID NAME
---------- --------------------
         1 A
         3 C
         4 C
         8 C
        10 D
         2 B
         5 C
         7 C
         6 C
         9 D
通過rownum<=5可以獲得前5行數據:
select * from test where rownum<=5;

        ID NAME
---------- --------------------
         1 A
         3 C
         4 C
         8 C
        10 D
如果你想獲得像top n那樣的結果,必須使用子查詢:
select * from (select * from test order by id) where rownum<=5;

        ID NAME
---------- --------------------
         1 A
         2 B
         3 C
         4 C
         5 C
如果你想獲得第5行到第10行之間的數據,則必須再加一層子查詢: 
 select T.* from (select t.*,rownum rn from (select * from test order by id) t where rownum<=10) T where T.rn>5;

        ID NAME                         RN
---------- -------------------- ----------
         6 C                             6
         7 C                             7
         8 C                             8
         9 D                             9
        10 D                            10
其實上面的寫法是由陷阱的,不信你把order by id換成order by name試試看:
select * from (select * from test order by name) where rownum<=5;

        ID NAME
---------- --------------------
         1 A
         2 B
         3 C
         4 C
         8 C
 select T.* from (select t.*,rownum rn from (select * from test order by name) t where rownum<=10) T where T.rn>5;

        ID NAME                         RN
---------- -------------------- ----------
         5 C                             6
         4 C                             7
         8 C                             8
        10 D                             9
         9 D                            10
你會驚奇的發現id=4這條數據出現在了兩個地方,這不合邏輯!但事實就是這樣的,為什麼呢?因為name不唯一,兩次排序取出的結果有可能會不一樣,我還是舉個例子吧:
 select id,name,rank() over(order by name) from test;

        ID NAME                 RANK()OVER(ORDERBYNAME)
---------- -------------------- -----------------------
         1 A                                          1
         2 B                                          2
         6 C                                          3
         3 C                                          3
         4 C                                          3
         8 C                                          3
         5 C                                          3
         7 C                                          3
         9 D                                          9
        10 D                                          9
從上面的結果我們不難發現,根據name排序,有多條數據並列排在第3位,這樣,當取前5名時,到底在並列第3中取哪幾位就不是確定的事,因此就出現了之前出現的詭異的問題。那麼,怎樣才能徹底解決這個問題呢?其實只要在order by name後面加上rowid,保證不會出現並列的情況就可以了,如下所示:
 select * from (select * from test order by name,rowid) where rownum<=5;

        ID NAME
---------- --------------------
         1 A
         2 B
         3 C
         4 C
         8 C
select T.* from (select t.*,rownum rn from (select * from test order by name,rowid) t where rownum<=10) T where T.rn>5;

        ID NAME                         RN
---------- -------------------- ----------
         5 C                             6
         7 C                             7
         6 C                             8
        10 D                             9
         9 D                            10

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved