Oracle分頁小談
【小編碎語】今天突然看到這篇文章,回想了一下原來,好像大家關注MySQL和SQL Server的分頁多一些,不知道是否也有人關注Oracle的分頁呢?借這個機會和大家分享一下Oracle的分頁吧!閑言到此,下面我們開始吧!
今天做項目時要實現分頁功能,以前只在mysql上弄過,oracle倒沒試過,但知道有這樣一個rownum這個東西。
但這個東西也不是那么容易用的,還是有蠻多地方要注意的。它不是物理上存在的一列,而是oracle自己在結果集中進行添加的。
首先我們來看一下我們的表結構先:
我們新建一個表:
也就一個字段ID而已,這方便我們直接地看到結果。
我們先隨便插入幾條數據:
先弄進去5條吧。
我們直接來一個:
- select rownum,id from test;
我們看到結果:
很高興吧,都是一模一樣的,ronwum和ID是一樣的,方便我們看。
但結果看到的結果可能就會讓你郁悶啦。
繼續下來,我們刪除幾條數據再插入幾條:
看到結果,我們是刪除了后面兩條,4,5這兩條記錄,而插入了8,9這兩條記錄。我們再來執行查詢:
- select rownum,id from test;
我們看到ID為8,9的已經取代了之前的4,5得到了rownum為4,5。這個說明了什么,說明了rownum并不是物理存在的,如果是物理存在的那么它肯定會隨著4,5的刪除而把rownum的4,5都刪除了,但它并沒有,而是把新插入的記錄的rownum作為此值,這說明rownum肯定只是一個邏輯上的列,它有一個專門的名稱——偽列。
下面我們繼續插入數據,方便做下面的實驗:
如果我們需要取得前5條記錄,我們會怎么做呢?我們看到前面的rownum是根據我們查出來的結果來進行賦值的,那么我們就明白了,也許可以這樣:
- select rownum,id from test where rownum <= 5 order by id;
但很杯具的是,我們錯了,看看結果:
為什么錯呢?
原因就是rownum會在我們查詢出來結果還沒排序前就進行編號。由于是這個原因,我們只要加個字查詢就OK啦。
- select rownum,id from (select * from test order by id) where rownum <= 5;
我們看看結果:
現在沒問題了,已經按照rownum來排序了,也就是實現了我們的要求,查出前5個。
不要高興的太早,查前5個沒問題,那中間的記錄呢,第2到5個呢,或者大于5呢。我們來看看:
- select rownum,id from (select * from test order by id) where rownum >=1 and rownum <= 4;
看看結果:
這個有數據,而且正常,很好。
但不要高興,我們分頁一般不會只要***條開始吧,如果要中間呢?我們看看:
- select rownum,id from (select * from test order by id) where rownum >= 2 and rownum <= 4;
這次不要大跌眼睛了:
杯具了吧。
為什么我們剛才拿到的>=1時會有呢,而現在>=2沒有呢?
原因就是oracle在賦值rownum的時候會從1開始賦值,而當我們進行rownum >=1時,由于=1這個條件是成立的,所以它可以繼續取下一條rownum,繼續賦值到2,接連賦值下去。
而當我們用rownum >=2時,由于=2這個條件是不成立的,因為當取到***條rownum=1時,會把它丟棄,而當取到下一條時,rownum還是為1,還是不滿足,一直這樣的循環,***的結果就是沒數據可查出了。
但我們分頁確實要這樣要進行,怎么辦呢?
其實也簡單,還是子查詢的方式,不是直接用rownum那我們把子查詢中的rownum命一個別名然后通過它來限定不就OK了。
我們看看:
- select rn,id from (select rownum as rn,id from (select * from test order by id) ) where rn >=2 and rn <= 4;
也許很多朋友看不明白是什么意思,我們先看看結果:
很正常,沒問題吧。
但為什么這樣就沒問題呢?其實我們在上面的子查詢中,直接把rownum用rn作為別名,它就被完全記錄下來了,這里我們用它來作限定條件已經不關原來的rownum的事了。之所以要用兩個子查詢是因為***個排序需要作為子查詢才可以取到正確的rownum,才可以定義別名。
相信看到這,大家都應該知道怎么用oracle來實現分頁啦。
這幾天工作忙啊,BlogWriter暫時進展不大,努力啊。
原文鏈接:http://cxshun.iteye.com/blog/1095793
【編輯推薦】