SQL查詢語句中的 limit offset(轉 )


經常用到在數據庫中查詢中間幾條數據的需求

比如下面的sql語句:

① selete * from testtable limit 2,1;

② selete * from testtable limit 2 offset 1;

注意:

1.數據庫數據計算是從0開始的

2.offset X是跳過X個數據,limit Y是選取Y個數據

3.limit  X,Y  中X表示跳過X個數據,讀取Y個數據

這兩個都是能完成需要,但是他們之間是有區別的:

①是從數據庫中第三條開始查詢,取一條數據,即第三條數據讀取,一二條跳過

②是從數據庫中的第二條數據開始查詢兩條數據,即第二條和第三條。

oracle數據庫不支持mysql中limit功能,但可以通過rownum來限制返回的結果集的行數,rownum並不是用戶添加的字段,而是oracle系統自動添加的。

(1)使查詢結果最多返回前10行:

select * from OB_CALL_DATA_LOG where rownum<=10;

(2)使查詢結果返回中間的10到100行:

如:     select * from OB_CALL_DATA_LOG rownum<101  minus  select * from OB_CALL_DATA_LOG rownum>9

注:select * from OB_CALL_DATA_LOG    and rownum>99 and rownum<101是錯誤的,oracle會認為條件不成立

 

這東西在分頁的時候十分有用.

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
在我們使用查詢語句的時候,經常要返回前幾條或者中間某幾行數據,這個時候怎么辦呢?不用擔心,mysql已經為我們提供了上面這樣一個功能。

LIMIT 子句可以被用於強制 SELECT 語句返回指定的記錄數。
LIMIT 接受一個或兩個數字參數。參數必須是一個整數常量。
如果給定兩個參數,第一個參數指定第一個返回記錄行的偏移量,第二個參數指定返回記錄行的最大數目。
初始記錄行的偏移量是 0(而不是 1): 為了與 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
mysql> SELECT * FROM table LIMIT 5,10; //檢索記錄行6-15
//為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個參數為 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 檢索記錄行 96-last.

//如果只給定一個參數,它表示返回最大的記錄行數目:
mysql> SELECT * FROM table LIMIT 5; //檢索前 5 個記錄行

//換句話說,LIMIT n 等價於 LIMIT 0,n。

原文鏈接

那么oracle中有limit嗎,答案是沒有。oracle中可以通過rownumber
Oracle使用rownum的關鍵字來實現這種查詢:
首先我們假設有一個地域信息表area,其表結構如下圖所示:


表中的數據如下圖所示(select * from area語句得到的結果):


1)查詢表中的前8條記錄
select * from area where rownum <= 8
查詢結果如下:

2)查詢第2到第8條記錄
對於這種形式的查詢,oracle不像mysql那么方便,它必須使用子查詢或者是集合操作來實現。我們可以使用以下3種方式可以實現:

A: select id,province,city,district from (select id,province,city,district,rownum as num from area) where num between 2 and 8;

首先根據select id,province,city,district,rownum as num from area得到一個臨時表,這個臨時表中有一個rownum列(一個偽列,類似與rowid,但又不同於rowid,因為rowid是物理存在的一個列,也就是說Oracle數據庫中任何一個表都有一個rowid列,而rownum不是物理存在的),然后在臨時表中來查詢。

B: select * from area where rownum <= 8 minus select * from area where rownum < 2;

使用集合減運算符minus,該操作返回在第一個select中出現而不在第二個select中出現的記錄。

C: select id,province,city,district from (select id,province,city,district,rownum as num from area) where num >=2

intersect

select * from area where rownum <= 8;

使用集合交運算符intersect,這里繞了一個彎(不過這個彎實現了rownum大於某個數的查詢),它是首先利用A的方式查詢得到所有rownum大於2的記錄,然后再與rownum小於等於8的記錄集合做交運算。三種操作得到的結果一樣,如下圖所示:


3)rownum需要注意的問題

[1] rownum不支持以下方式的查詢

a: select * from area where rownum > 2;

b: select * from area where rownum = n; –where n is a integer number lager than 1

注:rownum只支持select * from area where rownum =1的查詢。Oracle的官方文檔說明如下:

Conditions testing for ROWNUM values greater than a positive integer are always false.

For example, this query returns no rows:

SELECT * FROM employees

WHERE ROWNUM > 1;

The first row fetched is assigned a ROWNUM of 1 and makes the condition false. The

second row to be fetched is now the first row and is also assigned a ROWNUM of 1 and

makes the condition false. All rows subsequently fail to satisfy the condition, so no

rows are returned.

因為rownum是根據查詢的結果集來對記錄進行編號,所以當你查詢rownum大於2的記錄時會得到一個空的結果集。因為當oracle查詢得到第1條記錄時,發現rownum為1不滿足條件,然后就繼續查詢第2條記錄,但此時第2條記錄又被編號為1(也即rownum變為1),所以查詢得到的始終是rownum=1,因此無法滿足約束,最終查詢的結果集為空。

[2] rownum的排序查詢問題

Rownum的排序查詢是根據表中數據的初始順序來進行的。Oracle官方文檔中說明如下:

If an ORDER BY clause follows ROWNUM in the same query, then the rows will be

reordered by the ORDER BY clause. The results can vary depending on the way the

rows are accessed. For example, if the ORDER BY clause causes Oracle to use an index

to access the data, then Oracle may retrieve the rows in a different order than without

the index.

例如:select * from area where rownum <= 8 order by district;

其結果如下圖所示:


發現沒有,它只對area表中的前8條記錄進行排序。那么,如果我要取表中的前8條記錄並且要求是全表有序,那怎么辦呢?還是老辦法,使用子查詢。我們可以使用以下語句得到:

select * from (select * from area order by district)

where rownum <= 8;

查詢的結果如下圖所示:

結束語:

Oracle中的rownum與mysql的limit實現的功能相同,但沒有mysql來的容易,它一般通過一個子查詢來實現。mysql的易用性也是它能夠縱橫開源數據庫的原因,它不像postgresql那樣的學院派,它的那種簡單易用性或許在大型軟件項目的開發中值得借鑒。最近聽說sql server 2008也實現了limit的查詢,不過還沒去試過,Oracle在這方面也要加油啊,用戶容易使用才是王道

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM