今天作項目時要實現分頁功能,之前只在mysql上弄過,oracle倒沒試過,但知道有這樣一個rownum這個東西。mysql
但這個東西也不是那麼容易用的,仍是有蠻多地方要注意的。它不是物理上存在的一列,而是oracle本身在結果集中進行添加的。sql
首先咱們來看一下咱們的表結構先:oracle
咱們新建一個表:spa
也就一個字段ID而已,這方便咱們直接地看到結果。code
咱們先隨便插入幾條數據:排序
先弄進去5條吧。get
咱們直接來一個:test
- select rownum,id from test;
咱們看到結果:file
很高興吧,都是如出一轍的,ronwum和ID是同樣的,方便咱們看。select
但結果看到的結果可能就會讓你鬱悶啦。
繼續下來,咱們刪除幾條數據再插入幾條:
看到結果,咱們是刪除了後面兩條,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來實現分頁啦。