在oracle中ROWNUM是什么東西?拜托各位大神
ROWNUM是一個序列,是oracle數據庫從數據文件或緩沖區中讀取數據的順序。它取得第一條記錄則rownum值為1,第二條為2,依次類推。如果你用>,>=,=,between...and這些條件,因為從緩沖區或數據文件中得到的第一條記錄的rownum為1,則被刪除,接著取下條,可是它的rownum還是1,又被刪除,依次類推,便沒有了數據。 有了以上從不同方面建立起來的對 rownum 的概念,那我們可以來認識使用 rownum 的幾種現像 1. lect rownum,c1 from t1 where rownum != 10 為何是返回前9條數據呢?它與 lect rownum,c1 from tablename where rownum < 10 返回的結果集是一樣的呢? 因為是在查詢到結果集后,顯示完第 9 條記錄后,之后的記錄也都是 != 10,或者 >=10,所以只顯示前面9條記錄。也可以這樣理解,rownum 為9后的記錄的 rownum為10,因條件為 !=10,所以去掉,其后記錄補上,rownum又是10,也去掉,如果下去也就只會顯示前面9條記錄了 2. 為什么 rownum >1 時查不到一條記錄,而 rownum >0 或 rownum >=1 卻總顯示所以的記錄 因為rownum 是在查詢到的結果集后加上去的,它總是從1開始 3. 為什么 between 1 and 10 或者 between 0 and 10 能查到結果,而用 between 2 and 10 卻得不到結果 原因同上一樣,因為 rownum 總是從 1 開始 從上可以看出,任何時候想把 rownum = 1 這條記錄拋棄是不對的,它在結果集中是不可或缺的,少了rownum=1 就像空中樓閣一般不能存在,所以你的 rownum 條件要包含到 1 但如果就是想要用 rownum > 10 這種條件的話話就要用嵌套語句,把 rownum 先生成,然后對他進行查詢。 lect * from (let rownum as rn,t1.* from a where ...) where rn >10 一般代碼中對結果集進行分頁就是這么干的。 另外:rowid 與 rownum 雖都被稱為偽列,但它們的存在方式是不一樣的,rowid 可以說是物理存在的,表示記錄在表空間中的唯一位置ID,在DB中唯一。只要記錄沒被搬動過,rowid是不變的。rowid 相對于表來說又像表中的一般列,所以以 rowid 為條件就不會有 rownum那些情況發生。 另外還要注意:rownum不能以任何基表的名稱作為前綴。 oracle的rownum是在提取記錄就已經生成,它先于排序操作,所以必須使用子查詢先排序 。 ROWNUM值的分配是在查詢的謂詞解析之后,任何排序和聚合之前進行的。
Oracle 分頁查詢rownum的用法
對于rownum來說它是oracle系統順序分配為從查詢返回的行的編號,返回的第一行分配的是1,第二行是2,依此類推,這個偽字段可以用于限制查詢返回的總行數,且rownum不能以任何表的名稱作為前綴。
(1) rownum 對于等于某值的查詢條件
如果希望找到學生表中第一條學生的信息,可以使用rownum=1作為條件。但是想找到學生表中第二條學生的信息,使用rownum=2結果查不到數據。因為rownum都是從1開始,但是1以上的自然數在rownum做等于判斷是時認為都是fal條件,所以無法查到rownum = n(n>1的自然數)。
SQL> lect rownum,id,name from student where rownum=1;(可以用在限制返回記錄條數的地方,保證不出錯,如:隱式游標)
SQL> lect rownum,id,name from student where rownum =2;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
(2)rownum對于大于某值的查詢條件
如果想找到從第二行記錄以后的記錄,當使用rownum>2是查不出記錄的,原因是由于rownum是一個總是從1開始的偽列,Oracle 認為rownum> n(n>1的自然數)這種條件依舊不成立,所以查不到記錄。
查找到第二行以后的記錄可使用以下的子查詢方法來解決。注意子查詢中的rownum必須要有別名,否則還是不會查出記錄來,這是因為rownum不是某個表的列,如果不起別名的話,無法知道rownum是子查詢的列還是主查詢的列。
SQL>lect * from(lect rownum no ,id,name from student) where no>2;
NO ID NAME
---------- ------ ---------------------------------------------------
3 200003 李三
4 200004 趙四
(3)rownum對于小于某值的查詢條件
rownum對于rownum 1的自然數)的條件認為是成立的,所以可以找到記錄。
SQL> lect rownum,id,name from student where rownum lect * from (lect rownum no,id,name from student where rownum=2;
NO ID NAME
---------- ------ ---------------------------------------------------
2 200002 王二
3 200003 李三
(4)rownum和排序
Oracle中的rownum的是在取數據的時候產生的序號,所以想對指定排序的數據去指定的rowmun行數據就必須注意了。
SQL> lect rownum ,id,name from student order by name;
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
3 200003 李三
2 200002 王二
1 200001 張一
4 200004 趙四
可以看出,rownum并不是按照name列來生成的序號。系統是按照記錄插入時的順序給記錄排的號,rowid也是順序分配的。為了解決這個問題,必須使用子查詢;
SQL> lect rownum ,id,name from (lect * from student order by name);
ROWNUM ID NAME
---------- ------ ---------------------------------------------------
1 200003 李三
2 200002 王二
3 200001 張一
4 200004 趙四
這樣就成了按name排序,并且用rownum標出正確序號(有小到大)
rownum的理解
樓主您好
rownum是一個偽列,始終是從1開始的
所以我們比如要差第10行以后的數據,不能直接rownum>10
而必須把rownum字段取個別名作為一個子查詢,然后用這個新增的字段再>10這樣就是所謂的“固化”
Oracle之rownum(轉載)
一、rownum的說明
rownum是oracle特有的一個關鍵字。
(1)對于基表,在inrt記錄時,oracle就按照inrt的順序,將rownum分配給每一行記錄,因此在lect一個基表的時候,rownum的排序是根據inrt記錄的順序顯示的,例如:
(2)對于子查詢,則rownum的順序是根據子查詢的查詢順序進行動態分配的,例如:
由上圖可以看到T1_RN和T2_RN的區別。
t1中的rownum是根據emp這個基表的默認順序分配的,而內層子循環是根據SAL字段進行排序,所以t2的rownum是根據內層子查詢的記錄順序分配的。
----------------------------- 分 割 線 -------------------------------------
二、rownum的一些使用技巧
(1)使用rownum限制查詢返回的記錄數
1、例如,我們現在只想看到emp表中的第一條記錄:
將rownum限制為1,這樣就只能查詢出一條記錄。
2、現在,我們現在想查看emp中的前2條記錄:
將rownum的限制為2條,這樣就可以查詢出前2條記錄。
3、假如我們現在只想查看emp中的第二條記錄,又該如何寫語句呢?
如果我們先這樣寫:
where條件為:rownum=2,來看看查詢結果:
發現沒有查出任何數據,為什么呢?這里就要對oracle的rownum做進一步的理解。
因為rownum并不是當作實體數據存放在每一張表中,而是在每一次lect查詢的時候,根據基表的默認inrt順序由oracle動態分配的,有1才有2,如果rownum沒有1,那么2也就沒有了意義,所以這個查詢就不會有任何結果出來。這個時候我們就需要利用子查詢和別名列來實現這個需求:
首先通過子查詢,取出emp表的前2條記錄,并將子查詢中的rownum定義為別名rn,然后在外層查詢中,使用where條件使rn=2即可,查詢出emp表的第二條記錄:
Oracle數據庫rownum和row_number的不同點
明確對于rownum
來說它是oracle系統順序分配為從查詢返回的行的編號,返回的第一行分配的是1,第二行是二,以此類推,這個為字段可以用于限制查詢的返回的總行數,因為rownum總是從1開始,但是1以上的自然數在rownum
做等于判斷時都認為是fal
條件,所以無法查到
rownum=n
(n》1的自然數),所以查找第二行以后的記錄可以用子查詢方法來解決,給子查詢中的rownum取別名;對于小于某個值的情況兩種方法都差不多,但是對于某個不等于一的值或者求某個值到某個值之間的情況,用row_number()
別名獲得排名
,比用rownum偽列要簡單方便的多;因為偽列總是從一開始查找;
具體用法和區別參見以下代碼;
--取出工資最高的前5位
lect
empno,ename,sal,rownum
from
emp;
lect
*
from
(lect
*
from
emp
order
by
sal
desc)
where
rownum<=5;
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
as
num
from
emp)
where
num<=5;
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
from
emp)
where
rownum<=5
--工資的前3名
lect
*
from
emp
where
sal
>=any(lect
*
from
(lect
sal
from
emp
order
by
sal
desc)
where
rownum<=3);
lect
*
from(lect
*
from
emp
order
by
sal
desc)
where
rownum
<4;
lect
*
from
(lect
ename,sal,empno,deptno
,row_number()
over
(order
by
sal
desc)
from
emp)
where
rownum<4;
lect
*
from
(lect
ename,sal,empno,deptno
,row_number()
over
(order
by
sal
desc)
as
num
from
emp)
where
num<4
--按照工資排序,取出第6名到第10名
--使用偽列獲得
lect
*
from
(lect
ename,sal,rownum
r
from
(lect
*
from
emp
order
by
sal
desc)
where
rownum<=10)
where
r>5;
--使用排名函數獲得
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
as
num
from
emp)
where
num>5
and
num<=10;
-------
按工資從高到低獲得工資排名第四的員工
lect
*
from
(lect
ename,sal,row_number()
over(order
by
sal
desc)
as
num
from
emp)
where
num=4;
lect
*
from
(lect
ename,sal,rownum
r
from
(lect
*
from
emp
order
by
sal
desc)
where
rownum<=4)
where
r=4;
總結oracle中rownum和row_number()的區別
row_number()是分析函數,基本語法為row_number()
over(partition
by
字段
order
by
字段)
rownum是一個偽列
lect
*
from
dept
where
rownum<=3;
lect
*
from
dept
where
rownum
between
2
and
3;這兒會出錯,因為rownum的特性(沒有1就不會有2,沒有3)決定的
SELECT
*
FROM
(SELECT
A.*,ROWNUN
FROM
DEPT
A)T1
WHERE
T1.ROWNUM
BETWEEN
2
AND
3;這么寫不對,要這樣寫
SELECT
*
FROM
(SELECT
A.*,ROWNUM
RN
FROM
DEPT
A)T1
WHERE
T1.RN
BETWEEN
2
AND
3;
他們的主要區別是:使用rownum進行排序的時候是先對結果集加入偽列rownum然后再進行排序,而函數row_number()在包含排序從句后是先排序再計算行號碼。
oracle中ROWNUM使用
Q提出想要把tableA表按照col2列排序后,找出第5-10行記錄。咋搞?
按照特定條件查找出前N行數據,可以通過 ROWNUM 解決。
ROWNUM 又被稱為 偽列 ,偽列就像在在表中有這么一列,但并不存儲在表中,能夠基于偽列進行從查詢,也能夠基于 ROWNUM 進行更新刪除操作,例如
不過由于ROWNUM會隨著條件限制、表記錄更改等發生變化,并不是表記錄的真實值,所以盡量避免用ROWNUM來進行刪改操作。
ROWNUM 支持能夠查出正確記錄的操作符為<code><</code>、<code><=</code>、<code>!=</code>、<code>=1</code>,對于<code>></code>、<code>>=</code>、<code>=N(N>1)</code>、<code>BETWEEN…AND…</code>運行時不報錯,但直接使用不能查詢出正確結果。
ROWNUM 是在查詢出結果集后,給結果集添加上一個偽列,類似于給查詢出的結果標上序號,序號從1開始,連續遞增,不存在序號跳躍的現象。例如:
結果為:
如果加上限制條件:
結果為:
原來第4行會變成第3行,所以如果用<code>WHERE ROWNUM > 3</code>來進行查詢時,并不會有任何結果,因為第一條記錄(ROWNUM=1)不滿足條件被去掉后,原第二條記錄就成為第一條記錄(ROWNUM=1),仍舊不滿足被去掉,以此類推,所以永遠不會有大于3的記錄。由此,使用<code>ROWNUM != 2</code>與<code>ROWNUM < 2</code>等價。
回到剛開始的問題,既然ROWNUM不支持BETWEEN…AND…,>號這些,那如何得到第5-10行記錄呢?
可以通過使用子集查詢來解決:
使用了兩次子集查詢,第一次是按照col2進行排序,確保使用ROWNUM得到的是有序的結果集,第二次是用ROWNUM找出前10行記錄,并將ROWNUM起別名RID保存到臨時表,最后通過RID來限制第5行以后記錄。這樣就得到了第5-10有序記錄。
對于為何先使用ORDER BY 再使用ROWNUM<=10的解釋:
對于剛開始的問題,還可以使用以下子集查詢進行解決:
使用MINUS
使用INTERSECT
ORACLE中的rownum
ORACLE 中ROWNUM用法總結!