本文主要是以實例形式介紹了Oracle查詢中rownum與rowid的不同之處,以及以假設(shè)的方式為例,查詢條件為rownum = 2,在查詢出第一條記錄時的具體內(nèi)容的介紹。
在查詢中,我們可以注意到,類似于
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是在得到結(jié)果集的時候產(chǎn)生的,用于標(biāo)記結(jié)果集中結(jié)果順序的一個字段,這個字段被稱為“偽數(shù)列”,也就是事實上不存在的一個數(shù)列。它的特點是按順序標(biāo)記,而且是逐次遞加的,換句話說就是只有有rownum=1的記錄,才可能有rownum=2的記錄。
讓我們回頭來分析一下在where中使用rownum作為Oracle查詢條件的情況。在取rownum=1,或者rownum = n (n>1)的時候,沒有問題。那么為什么當(dāng)條件為rownum = n或者rownum >= n時明明有數(shù)據(jù)卻只能得到一個空集呢?假設(shè)我們的查詢條件為rownum = 2,那么在查詢出的第一條記錄的時候,Oracle標(biāo)記此條記錄rownum為1,結(jié)果發(fā)現(xiàn)和rownum=2的條件不符,于是結(jié)果集為空。
假如有一條查詢語句為
select xx,yy from table where zz > 20 and rownum 10
那么在執(zhí)行的時候,是先按照zz>20的條件查詢出一個結(jié)果集,然后按照rownum取出前10條返回?還是在按照zz>20的條件先查詢,然后有一個記錄就標(biāo)記一個rownum,到rownum10的時候就停止查詢?個人感覺應(yīng)該是后者,也就是在執(zhí)行語句的時候,不是做full scan,而是取夠數(shù)據(jù)就停止查詢。
要驗證這個想法應(yīng)該很簡單,找一個數(shù)據(jù)量非常大的表進行Oracle查詢就可以了??上壳拔覜]有這樣的表,有條件的讀者可以自己測試一下。
我們可以看出,直接使用rownum是要受到限制的。但是很容易遇到這樣的需求“查出符合條件的第xx條到第xx條記錄”,比如頁面的分頁處理。這個時候如何構(gòu)造出適合自己的結(jié)果集?
當(dāng)然全取出來手工挑選也是可以的,但是前提是整個數(shù)據(jù)集的數(shù)據(jù)條數(shù)不多的情況下。假如遇到上十萬百條的數(shù)據(jù),全部取出來的話,用戶就不用干別的事情了。這個時候用戶應(yīng)該怎么做呢?當(dāng)然就是要用到我們介紹的rownum拉!rownum不是個“偽數(shù)列”么,好說,我們現(xiàn)在把它弄成一個實在的字段就可以了。
具體做法就是利用子Oracle查詢,在構(gòu)建臨時表的時候,把rownum也一起構(gòu)造進去。比如
select xx,yy from (select xx,yy,rownum as xyz from table where zz >20) where xyz between 10 and 20
這樣就可以了。
另外使用Oracle提供的結(jié)果集處理函數(shù)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還提供了另外一個偽數(shù)列:rowid。不過rowid和rownum不同,一般說來每一行數(shù)據(jù)對應(yīng)的rowid是固定而且唯一的,在這一行數(shù)據(jù)存入數(shù)據(jù)庫的時候就確定了??梢岳胷owid來查詢記錄,而且通過rowidOracle查詢記錄是查詢速度最快的查詢方法。
對于這個我沒有試過,另外要記住一個長度在18位,而且沒有太明顯規(guī)律的字符串是一個很困難的事情,所以我個人認為利用rowid查詢記錄的實用性不是很大。此外rowid只有在表發(fā)生移動(比如表空間變化,數(shù)據(jù)導(dǎo)入/導(dǎo)出以后),才會發(fā)生變化。
您可能感興趣的文章:- oracle 使用rownum的三種分頁方式
- mysql類似oracle rownum寫法實例詳解
- oracle中利用關(guān)鍵字rownum查詢前20名員工信息及rownum用法
- Oracle數(shù)據(jù)庫rownum和row_number的不同點
- oracle中rownum和row_number()
- 隨機獲取oracle數(shù)據(jù)庫中的任意一行數(shù)據(jù)(rownum)示例介紹
- Oracle中使用Rownum分頁詳細例子
- oracle的rownum深入解析
- ORACLE數(shù)據(jù)庫中Rownum用法詳解