在 Oracle 資料庫中,由於不支援 SELECT TOP N 語法,開發人員通常透過 ROWNUM 搭配子查詢與排序來實現「取前 N 筆資料」的需求。本文將系統性說明基本 Top N 查詢、從 Top N 中取第 M 筆、取第 N 筆資料,以及分頁查詢(取第 M 筆起的 X 筆)四種常見場景的 SQL 寫法與原理。
核心邏輯:先在內層查詢中排序,再在外層用 ROWNUM 過濾。注意 ROWNUM 是在資料取出後才產生的偽欄位,因此必須先排序再限制筆數。
SELECT * FROM (
SELECT * FROM customer ORDER BY name
)
WHERE ROWNUM <= 3
ORDER BY ROWNUM ASC;
範例資料為客戶名稱(first, second, third...),依字母序取前三筆,結果為 eighth、fifth、first。
需在中層查詢中將 ROWNUM 顯式命名為 RECNO,最外層再依 RECNO 過濾。
SELECT id, name FROM (
SELECT ROWNUM recno, id, name FROM (
SELECT * FROM customer ORDER BY name
)
WHERE ROWNUM <= 3
ORDER BY ROWNUM ASC
)
WHERE recno = 2;
結果為第五筆資料(fifth)。
此為上一種情況的特例(M=N),內層 ROWNUM 限制可直接設為 N,減少不必要的資料讀取。
SELECT id, name FROM (
SELECT ROWNUM recno, id, name FROM (
SELECT * FROM customer ORDER BY name
)
WHERE ROWNUM <= 2
ORDER BY ROWNUM ASC
)
WHERE recno = 2;
內層 ROWNUM 上限設為 M + X - 1,外層用 BETWEEN M AND (M + X - 1) 過濾。此模式易擴充為儲存程序,支援動態分頁參數。
SELECT id, name FROM (
SELECT ROWNUM recno, id, name FROM (
SELECT * FROM customer ORDER BY name
)
WHERE ROWNUM <= (2 + 3 - 1)
ORDER BY ROWNUM ASC
)
WHERE recno BETWEEN 2 AND (2 + 3 - 1);
結果為 fifth、first、forth 三筆資料。
掌握「子查詢排序 → ROWNUM 限制 → 外層再篩選」的三層結構,即可靈活應對 Oracle 各類 Top N 与分頁需求。實務上建議封裝為函式或程序,提升維護性與效能。