Oracle中rowid和rownum區別

來源:互聯網
上載者:User

rowid和rownum都是虛列,但含義完全不同。rowid是物理地址,用於定位oracle中具體資料的實體儲存體位置,而rownum則是sql的輸出結果排序,從下面的例子可以看出其中的區別。

rowid是 string 類型,rownum 是 number 類型

rowid是物理地址,插入資料時產生

rownum是查詢時產生,從1開始累加,

select int_id ,rowid from bts_x where rowid>'0'(查詢結果是所有)

select int_id ,rowid from bts_x where rowid>0(語句報錯,類型不相匹配)

select int_id from bts_x where rownum>1 查詢結果是零

select int_id from bts_x where rownum>0(>=1)查詢結果是所有

select int_id from bts_x t where rownum <20(查詢結果是19條)

select int_id from bts_x where rownum<40 and rownum>20(查詢結果是0條)
select int_id from bts_x where rownum>20 and rownum<40(查詢結果是0條)

根據rownum取第11至20條資料:

正確寫法:

select int_id, xyz
  from (select int_id, rownum xyz
          from (select int_id from bts_x t order by int_id desc) t1)
 where xyz > 10
   and xyz <= 20

錯誤寫法:

select int_id, rownum xyz
          from (select int_id from bts_x t order by int_id desc) t1
          where rownum>10 and rownum<20(查出的資料為0條,錯在rownum>10 and rownum<=20)

以上為自己測試結果。

 

以下為網上轉載:

http://school.cnd8.com/oracle/jiaocheng/26482.htm

在Oracle中,有一個很有趣的東西,那就是rownum。當你從某個表中查詢資料的時候,返回的結果集中都會帶有rownum這個欄位,而且有時候也可以使用rownum進行一些條件查詢。

  在查詢中,我們可以注意到,類似於“select xx from table where rownum < n”(n>1)這樣的查詢是有正確含義的,而“select xx from table where rownum = n”這樣的查詢只在n=1的時候成立,“select xx from table where rownum > n”(n>1)這樣的查詢只能得到一個空集。另外“select xx from table where rownum > 0”這個查詢會返回所有的記錄。這是為什麼呢?原因就在於Oracle對rownum的處理上,rownum是在得到結果集的時候產生的,用於標記結果集中結果順序的一個欄位,這個欄位被稱為“偽數列”,也就是事實上不存在的一個數列。它的特點是按順序標記,而且是逐次遞加的,換句話說就是只有有rownum=1的記錄,才可能有rownum=2的記錄。

  讓我們回頭來分析一下在where中使用rownum作為查詢條件的情況。在rownum取=1,或者rownum <= n (n>1)的時候,沒有問題。那麼為什麼當條件為rownum = n或者rownum >= n時明明有資料卻只能得到一個空集呢?假設我們的查詢條件為rownum = 2,那麼在查詢出的第一條記錄的時候,oracle標記此條記錄rownum為1,結果發現和rownum=2的條件不符,於是結果集為空白。寫到這裡,我忽然有一個有趣的想法:假如有一條查詢語句為select xx,yy from table where zz > 20 and rownum < 10,那麼在執行的時候,是先按照zz>20的條件查詢出一個結果集,然後按照rownum取出前10條返回?還是在按照zz>20的條件先查詢,然後有一個記錄就標記一個rownum,到rownum<10的時候就停止查詢?我覺得應該是後者,也就是在執行語句的時候,不是做full scan,而是取夠資料就停止查詢。要驗證這個想法應該很簡單,找一個資料量非常大的表進行查詢就可以了。可惜目前我沒有這樣的表。

  我們可以看出,直接使用rownum是要受到限制的。但是很容易遇到這樣的需求“查出合格第xx條到第xx條記錄”,比如頁面的分頁處理。這個時候如何構造出適合自己的結果集?嗯,牆邊那位說全取出來手工挑選的哥們可以拉出去了。當然這樣做也是可以的,但是前提是整個資料集的資料條數不多的情況下。假如遇到上十萬百條的資料,全部取出來的話,使用者就不用幹別的事情了。這個時候使用者應該怎麼做呢?當然就是要用到我們介紹的rownum拉!rownum不是個“偽數列”麼,好說,我們現在把它弄成一個實在的欄位就可以了。具體做法就是利用子查詢,在構建暫存資料表的時候,把rownum也一起構造進去。比如“select xx,yy from (select xx,yy,rownum as xyz from table where zz >20) where xyz between 10 and 20”這樣就可以了。另外使用oracle提供的結果集處理函數minus也可以做到,例如“select xx,yy from table where zz > 20 and rownum <20 minus select xx,yy from table where zz>20 and rownum <10”,但是使用minus好像比使用子查詢更加消耗資源。

  和rownum相似,oracle還提供了另外一個偽數列:rowid。不過rowid和rownum不同,一般說來每一行資料對應的rowid是固定而且唯一的,在這一行資料存入資料庫的時候就確定了。可以利用rowid來查詢記錄,而且通過rowid查詢記錄是查詢速度最快的查詢方法。(這個我沒有試過,另外要記住一個長度在18位,而且沒有太明顯規律的字串是一個很困難的事情,所以我個人認為利用rowid查詢記錄的實用性不是很大)rowid只有在表發生移動(比如資料表空間變化,資料匯入/匯出以後),才會發生變化。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.