1. 程式人生 > >Oracle中rownum機制原理&用法詳解

Oracle中rownum機制原理&用法詳解

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

2. 特點
關於rownum有以下主要特點:

1)rownum不屬於任何表。
2)rownum存在的前提,先有結果表。
3)rownum總是從1開始。
4)rownum一般只和<(<=)一起用。
5)使用rownum進行分頁查詢需要把rownum轉化為實列,並針對rownum查詢。
2. 機制原理
rownum的用法看似奇怪,其實如果明白其機制原理就會很簡單。
首先我們來做個簡單的實驗:從dual表中取出所有的欄位,並取出rownum。
如果我們採用如下的寫法:t.rownum

這樣執行就會報01747錯:


因為實際上,dual表就不存在rownum這個欄位,所以我們無法使用t.rownum的格式。
正確的寫法,應該是:

所以,rownum是一個虛列,不屬於任何表。

那麼這虛列是怎麼來的。我們在做個簡單的實驗,便於理解:
如下,我們有一個簡單的表:test_ljb,共有十條記錄。
我們加上rownum。

結果如下,很好理解,選出十條記錄,rownum從1到10


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

結果如下:選出三條記錄,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。

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

統統都是沒結果的。

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

3. 用法
那有的同學就犯嘀咕了,我要做大於查詢怎麼搞啊,分頁查詢怎麼搞啊,人家Mysql和Hive一個limit a, b 直接完事,你Oracle怎麼搞。
其實方法還是有的,也是用rownum,不過要先把這貨轉化為實列。加個子查詢就可以了。
老套路,簡單實驗走一波。

3.1 大於查詢
還是test_ljb表,就選>5行。

3.2.1 簡單分頁查詢

3.3.2 排序分頁查詢
排序分頁查詢就麻煩了,首先要排序,然後再排序的基礎上再篩選。
當然這個也是實際專案最常用的。
選出薪水最高的第4、5、6個。

 

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

結果如下:

注:這裡寫SQL語句時,注意縮排,有利於思路流暢。


---------------------
作者:大資料JavaLiu_Arvin
來源:CSDN
原文:https://blog.csdn.net/qq_36743482/article/details/78919904
版權宣告:本文為博主原創文章,轉載請附上博文連結!