你聽過Oracle中rownum用法嗎?

2021-09-26 04:20:20 字數 3099 閱讀 2963

rownum是oracle引入的虛列。 

在物理上這個虛列並不存在,只是在查詢時才構造出來。偽列通常是自由分配的,使用者無法執行修改等操作。

關於rownum有以下主要特點:

rownum的用法看似奇怪,其實如果明白其機制原理就會很簡單。 

首先我們來做個簡單的實驗:從dual表中取出所有的字段,並取出rownum。 

如果我們採用如下的寫法:t.rownum

select t.*,t.rownum from dual t;
這樣執行就會報01747錯: 

因為實際上,dual表就不存在rownum這個字段,所以我們無法使用t.rownum的格式。 

正確的寫法,應該是:

select t.*, rownum from dual t;
所以,rownum是乙個虛列,不屬於任何表。

那麼這虛列是怎麼來的。我們在做個簡單的實驗,便於理解: 

如下,我們有乙個簡單的表:test_ljb,共有十條記錄。 

我們加上rownum。

select t.*, rownum from test_ljb t;
結果如下,很好理解,選出十條記錄,rownum從1到10 

我們加上乙個salary的篩選條件:

select t.*, rownum from test_ljb t where t.salary>1200;
結果如下:選出三條記錄,rownum從1到3 

需要注意的是,第二個結果表的rownum對應的employee和第一張並不對應。 

如:在第一張表rownum為1時,對應的時arvin,而第二張對應的是oracle。

原因如下: 

因為rownum是對結果集加的乙個偽列,即先查到結果集之後再加上去的乙個列。 

簡單的說,rownum是對符合條件結果的序列號。它總是從1開始排起的,所以選出的結果不可能跳過1,而有其他大於1的值。 

或者說,rownum是乙個動態的,根據新的結果集實時變化的。

比如,如下語句:

select t.*, rownum from test_ljb t where rownum >1; --大於2、3或者其他任何大於1的值,結果相同。
我們發現沒有符合條件的記錄。

根據原理,rownum是對結果集的從1開始排。那麼以上的語句的結果集是什麼呢?

事實上,當執行完from test_ljb時,我們可以把他當作時乙個結果表,rownum是從1-10。 

然後,重點,當我們執行過濾條件,rownum>1 時,第一條記錄不滿足,剔除。這個時候,新的結果集產生了,原來的第二條記錄就成了第一條,相應的rownum變為了1-9。 

再次比較原來的第一條,現在的第二條記錄,他的rownum也是1,也不滿足,rownum是1-8。 

以此類推,流水的記錄,鐵打的rownum從1開始。所以,直到rownum是1,還不滿足。所以最後沒有記錄被篩選出來,也沒了rownum。

所以,我們寫出的這類語句:

rownum>1

rownum>5 and rownum<10

rownum between 6 and 9

統統都是沒結果的。

不過有意思的是,選出前十條,可以有好多寫法:

rownum<=10

rownum<11

rownum<>11 --不等於,根據原理應該很好理解,不贅述

rownum!=11 --不等於

那有的同學就犯嘀咕了,我要做大於查詢怎麼搞啊,分頁查詢怎麼搞啊,人家mysql和hive乙個limit a, b 直接完事,你oracle怎麼搞。 

其實方法還是有的,也是用rownum,不過要先把這貨轉化為實列。加個子查詢就可以了。 

老套路,簡單實驗走一波

還是test_ljb表,就選》5行。

select * from 

( select t.*,rownum r from test_ljb t

)twhere t.r>5;

select * from 

( select t.*,rownum r from test_ljb t

)twhere t.r>3 and t.r<6

排序分頁查詢就麻煩了,首先要排序,然後再排序的基礎上再篩選。 

當然這個也是實際專案最常用的。 

選出薪水最高的第4、5、6個。

select rst.* from 

( select t2.*,rownum r2 from

(select t.*,rownum r1 from test_ljb t order by nvl(salary,0) desc

--這裡需要說明的是,rownum僅僅針對新的結果集動態標記,而排序並不會生成新的結果集。

--所以這條語句的rownum看起來並不是按照1-10的順序排列。

--事實上,這裡的rownum r1並不會用到,為了看起來更加直觀,加上的。

)t2)rst

where rst.r2 between 4 and 6;

這裡需要注意的是:rownum僅僅針對新的結果集動態標記,而排序並不會生成新的結果集,如果僅僅執行

select t.*,rownum r1 from test_ljb t order by nvl(salary,0) desc
結果如下: 

名人名言,你聽過幾句

青年時種下什麼,老年時就收穫什麼。易卜生 人並不是因為美麗才可愛,而是因為可愛才美麗。托爾斯泰 人的美德的榮譽比他的財富的榮譽不知大多少倍。達 芬奇 人的生命是有限的,可是,為人民服務是無限的,我要把有限的生命,投入到無限的為人民服務之中去。雷鋒 人的天職在勇於探索真理。哥白尼 人的知識愈廣,人的本...

沒聽過這些網頁翻譯外掛程式,你還敢說你用谷歌瀏覽器?

1 fireshot你經常在網頁上截圖嗎?大神經常發到論壇上的長圖你知道怎麼來的嗎?猜對了!fireshot可以做到。有了他可以很方便地以的形式儲存和分享一些網頁內容。傳送門 2 advertising terminator 有些 的廣告簡直過分到無法接受!但是有了advertising termi...

你可能從未聽過的 Linux 發行版

官方主頁 官方主頁 rosa linux 基於 mandriva,以 kde 4 作為預設桌面環境。此外,rosa 也提供伺服器版本 針對教師的 classroom 版本 及適合交通的人造衛星資訊系統。官方主頁 cinnarch 的特色是包含 cinnamon 桌面環境及 lightdm 登入管理器...