Oracle查詢(xún)語(yǔ)句中rownum與rowid的不同之處分析
本文主要是以實(shí)例形式介紹了Oracle查詢(xún)中rownum與rowid的不同之處,以及以假設(shè)的方式為例,查詢(xún)條件為rownum = 2,在查詢(xún)出第一條記錄時(shí)的具體內(nèi)容的介紹。
在查詢(xún)中,我們可以注意到,類(lèi)似于
select xx from table where rownum < n (n>1)
這樣的查詢(xún)是有正確含義的,而
select xx from table where rownum = n
這樣的查詢(xún)只在n=1的時(shí)候成立,
select xx from table where rownum > n (n>1)
這樣的查詢(xún)只能得到一個(gè)空集。
另外
select xx from table where rownum > 0
這個(gè)查詢(xún)會(huì)返回所有的記錄。這是為什么呢?原因就在于Oracle對(duì)rownum的處理上,rownum是在得到結(jié)果集的時(shí)候產(chǎn)生的,用于標(biāo)記結(jié)果集中結(jié)果順序的一個(gè)字段,這個(gè)字段被稱(chēng)為“偽數(shù)列”,也就是事實(shí)上不存在的一個(gè)數(shù)列。它的特點(diǎn)是按順序標(biāo)記,而且是逐次遞加的,換句話說(shuō)就是只有有rownum=1的記錄,才可能有rownum=2的記錄。
讓我們回頭來(lái)分析一下在where中使用rownum作為Oracle查詢(xún)條件的情況。在取rownum=1,或者rownum <= n (n>1)的時(shí)候,沒(méi)有問(wèn)題。那么為什么當(dāng)條件為rownum = n或者rownum >= n時(shí)明明有數(shù)據(jù)卻只能得到一個(gè)空集呢?假設(shè)我們的查詢(xún)條件為rownum = 2,那么在查詢(xún)出的第一條記錄的時(shí)候,Oracle標(biāo)記此條記錄rownum為1,結(jié)果發(fā)現(xiàn)和rownum=2的條件不符,于是結(jié)果集為空。
假如有一條查詢(xún)語(yǔ)句為
select xx,yy from table where zz > 20 and rownum < 10
那么在執(zhí)行的時(shí)候,是先按照zz>20的條件查詢(xún)出一個(gè)結(jié)果集,然后按照rownum取出前10條返回?還是在按照zz>20的條件先查詢(xún),然后有一個(gè)記錄就標(biāo)記一個(gè)rownum,到rownum<10的時(shí)候就停止查詢(xún)?個(gè)人感覺(jué)應(yīng)該是后者,也就是在執(zhí)行語(yǔ)句的時(shí)候,不是做full scan,而是取夠數(shù)據(jù)就停止查詢(xún)。
要驗(yàn)證這個(gè)想法應(yīng)該很簡(jiǎn)單,找一個(gè)數(shù)據(jù)量非常大的表進(jìn)行Oracle查詢(xún)就可以了。可惜目前我沒(méi)有這樣的表,有條件的讀者可以自己測(cè)試一下。
我們可以看出,直接使用rownum是要受到限制的。但是很容易遇到這樣的需求“查出符合條件的第xx條到第xx條記錄”,比如頁(yè)面的分頁(yè)處理。這個(gè)時(shí)候如何構(gòu)造出適合自己的結(jié)果集?
當(dāng)然全取出來(lái)手工挑選也是可以的,但是前提是整個(gè)數(shù)據(jù)集的數(shù)據(jù)條數(shù)不多的情況下。假如遇到上十萬(wàn)百條的數(shù)據(jù),全部取出來(lái)的話,用戶(hù)就不用干別的事情了。這個(gè)時(shí)候用戶(hù)應(yīng)該怎么做呢?當(dāng)然就是要用到我們介紹的rownum拉!rownum不是個(gè)“偽數(shù)列”么,好說(shuō),我們現(xiàn)在把它弄成一個(gè)實(shí)在的字段就可以了。
具體做法就是利用子Oracle查詢(xún),在構(gòu)建臨時(shí)表的時(shí)候,把rownum也一起構(gòu)造進(jìn)去。比如
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好像比使用子查詢(xún)更加消耗資源。
和rownum相似,Oracle還提供了另外一個(gè)偽數(shù)列:rowid。不過(guò)rowid和rownum不同,一般說(shuō)來(lái)每一行數(shù)據(jù)對(duì)應(yīng)的rowid是固定而且唯一的,在這一行數(shù)據(jù)存入數(shù)據(jù)庫(kù)的時(shí)候就確定了??梢岳胷owid來(lái)查詢(xún)記錄,而且通過(guò)rowidOracle查詢(xún)記錄是查詢(xún)速度最快的查詢(xún)方法。
對(duì)于這個(gè)我沒(méi)有試過(guò),另外要記住一個(gè)長(zhǎng)度在18位,而且沒(méi)有太明顯規(guī)律的字符串是一個(gè)很困難的事情,所以我個(gè)人認(rèn)為利用rowid查詢(xún)記錄的實(shí)用性不是很大。此外rowid只有在表發(fā)生移動(dòng)(比如表空間變化,數(shù)據(jù)導(dǎo)入/導(dǎo)出以后),才會(huì)發(fā)生變化。
- Oracle如何通過(guò)執(zhí)行計(jì)劃查看查詢(xún)語(yǔ)句是否使用索引
- ORACLE中關(guān)于表的一些特殊查詢(xún)語(yǔ)句
- Oracle 多參數(shù)查詢(xún)語(yǔ)句
- Oracle、MySQL和SqlServe三種數(shù)據(jù)庫(kù)分頁(yè)查詢(xún)語(yǔ)句的區(qū)別介紹
- 45個(gè)非常有用的 Oracle 查詢(xún)語(yǔ)句小結(jié)
- oracle數(shù)據(jù)庫(kù)常用的99條查詢(xún)語(yǔ)句
- oracle常用sql查詢(xún)語(yǔ)句部分集合(圖文)
- oracle查詢(xún)語(yǔ)句大全(oracle 基本命令大全一)
- Oracle?查詢(xún)語(yǔ)句限制只選擇最前面幾行和最后面幾行的實(shí)現(xiàn)方式
相關(guān)文章
使用Navicat Premium工具將oracle數(shù)據(jù)庫(kù)遷移到MySQL
最近的業(yè)務(wù)項(xiàng)目需求,因此總結(jié)遇到的問(wèn)題。使用Navicat Premium工具將Oralce數(shù)據(jù)庫(kù)遷移到MySQL,本文通過(guò)圖文的形式給大家詳細(xì)介紹,感興趣的朋友跟隨小編一起看看吧2021-05-05檢測(cè)oracle數(shù)據(jù)庫(kù)壞塊的方法
這篇文章主要介紹了檢測(cè)oracle數(shù)據(jù)庫(kù)壞塊的方法 的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-05-05Oracle minus用法詳解及應(yīng)用實(shí)例
這篇文章主要介紹了Oracle minus用法詳解及應(yīng)用實(shí)例的相關(guān)資料,這里對(duì)oracle minus的用法進(jìn)行了具體實(shí)例詳解,需要的朋友可以參考下2017-01-01oracle Dbeaver存儲(chǔ)過(guò)程語(yǔ)法詳解
這篇文章主要介紹了oracle Dbeaver存儲(chǔ)過(guò)程語(yǔ)法詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10Oracle使用like查詢(xún)時(shí)對(duì)下劃線的處理方法
這篇文章主要介紹了Oracle使用like查詢(xún)時(shí)對(duì)下劃線的處理方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03