ROWNUM 是 Oracle 中最常用也最易誤解的偽欄位。許多開發者僅知其「支援 <、<=、!=,不支援 >、>=、=、BETWEEN」的表面規則,卻不懂底層原理,導致查詢結果違背直覺。本文從核心機制出發,徹底解析 ROWNUM 行為邏輯,並提供正確分頁寫法。
ROWNUM 是在查詢產生結果集後,依序分配給各行的流水號,永遠從 1 開始遞增。 關鍵點:
ROWNUM > 1 過濾掉,第二筆遞補成為第一筆,ROWNUM 仍為 1,故永無符合條件記錄| 查詢條件 | 結果 | 原因 |
|---|---|---|
ROWNUM < 10 | 前 9 筆 | 符合直覺,前 9 筆 ROWNUM 1-9 滿足條件 |
ROWNUM > 10 | 零筆 | 第一筆 ROWNUM=1 不滿足被捨棄,後續遞補皆為 1,永無滿足條件者 |
ROWNUM != 10 | 前 9 筆 | 第 10 筆 ROWNUM=10 被排除,第 11 筆遞補為 10 又被排除,以此類推 |
BETWEEN 2 AND 10 | 零筆 | 同理,缺少 ROWNUM=1 導致後續無法產生 |
需先在子查詢中產生 ROWNUM 作為實體欄位,外層再對其篩選:
SELECT *
FROM (SELECT ROWNUM AS rn, t1.*
FROM your_table t1
WHERE ...)
WHERE rn > 10; -- 現在可正確取得第 11 筆之後資料
此模式為標準分頁實作基礎,配合 rn BETWEEN :start AND :end 即可實現任意頁面查詢。
因此 ROWID 可直接作為查詢條件,不受 ROWNUM 類限制。
t1.ROWNUM 會報錯)ORDER BY 時,ROWNUM 分配發生在排序前,需用子查詢先排序再取 ROWNUM理解 ROWNUM「先有結果集、從 1 開始遞增」的核心機制,所有看似詭異的行為皆迎刃而解。掌握子查詢物化技巧,即可靈活實現高效分頁與複雜條件篩選,是 Oracle 開發者的必修內功。