Oracle - Select指定傳回筆數

由於Oracle不支持Select Top語句,所以在Oracle中經常是用Order By跟rownum的組合來實現Select Top N的查詢,
也跟PostgreSQL下的方法不一樣,不是用limit限制資料筆數,因此做記錄。

OS: 整理完後我開始懷念PostgreSQL語法的簡潔…

Oracle中 Select指令沒有類似LIMIT的參數可以使用來限制傳回資料的筆數,但是可以利用 ORACLE中的Rownum的值作一點手腳來限制傳回值的範圍。

ROWNUM 說明:

  • rownum不能以任何表的名稱作為前綴字。
  • Oracle 使用 rownum 作為查詢結果行的編號,第一行是1,第二行是2, 以此類推,可以用於限制查詢返回的總行數。
  • rownum的值在”查詢結果輸出時自動產生”,因此第一條始終是1。
  • Oracle中的rownum的是在查找資料的時候產生的序號,所以想對指定排序的數據去指定的rowmun行數據就必須注意了。
  • 要注意的是在使用rownum時,只有當Order By 的字段是主鍵或索引時,查詢結果才會先排序再計算rownum,但是,對非主鍵欄位進行排序時卻不是。
    出現這種的原因是:Oracle 先按物理存儲位置(rowid)順序取出滿足rownum 條件的記錄,即物理位置上的前5條數據,然後在對這些數據按照Order By 的字段進行排序,而不是我們所期望的先排序、再取特定記錄數。(因此排序的欄位建議是有索引的欄位)
  • 若無索引或主鍵,只能用子查詢來實現先排序。(注意查詢效能的問題)

1、ROWNUM 是偽列,必須要有返回結果後,每條返回記錄就會對應產生一個ROWNUM數值;
2、返回結果記錄的ROWNUM 是從1 開始排序的,因此第一條始終是1;這樣,當查詢到第一條記錄時,該記錄的ROWNUM 為1,但條件要求ROWNUM>1,因此不符合,繼續查詢下一條;因為前面沒有符合要求的記錄,因此下一條記錄過來後,其ROWNUM 還是為1,如此循環,就不會產生結果。

分頁顯示實作:

通用的作法:
select * from (子查詢) WHERE rownum Between 初始列 AND 尾列;

Tips:

  • 很多開發者在確認某個表中是否有相應數據時,喜歡加上ROWNUM=1,其想法就是只要存在一條數據就說明有相應數據,查詢就可以直接返回了,這樣就能提高性能了。
    但是在Oracle 10G之前,使用rownum=1 是不能達到預期的性能效果的,而是需要通過<2 或<=1 作為過濾條件才能達到預期效果。

Oracle rownum 用法詳解
Oracle rownum 注意事項