表 table1,主鍵 ID 為自增但**可能不連續**。要求查詢第 31-40 行記錄 (按 ID 排序)。
SELECT * FROM table1 ORDER BY ID LIMIT 10 OFFSET 30;
-- 或
SELECT * FROM table1 ORDER BY ID LIMIT 30, 10;
原理: OFFSET 30 跳過前 30 行,LIMIT 10 取後 10 行。最簡潔、效能最好 (配合索引)。
-- SQL Server 2012+
SELECT * FROM table1 ORDER BY ID OFFSET 30 ROWS FETCH NEXT 10 ROWS ONLY;
-- SQL Server 2008/2005 (經典三層嵌套)
SELECT TOP 10 * FROM (
SELECT TOP 40 * FROM table1 ORDER BY ID
) AS t ORDER BY ID DESC;
舊版邏輯: 先取前 40 行,再倒序取前 10 行,再正序 (或應用層反轉)。
-- Oracle 12c+ (標準 SQL)
SELECT * FROM table1 ORDER BY ID OFFSET 30 ROWS FETCH NEXT 10 ROWS ONLY;
-- Oracle 11g 及之前 (ROWNUM 雙層嵌套)
SELECT * FROM (
SELECT t.*, ROWNUM rn FROM (
SELECT * FROM table1 ORDER BY ID
) t WHERE ROWNUM <= 40
) WHERE rn > 30;
關鍵點: Oracle ROWNUM 在 WHERE 過濾**前**賦值,故需雙層嵌套:內層排序並限制 ROWNUM <= 40,外層過濾 rn > 30。
SELECT * FROM table1 ORDER BY ID FETCH FIRST 10 ROWS ONLY OFFSET 30 ROWS;
| 寫法 | 適用場景 | 效能 | 可移植性 |
|---|---|---|---|
LIMIT offset, count | MySQL, PG, SQLite | ⭐⭐⭐ (索引友好) | 低 |
OFFSET ... FETCH | SQL:2008 標準 (PG, Oracle 12c+, SQL Server 2012+, DB2) | ⭐⭐⭐ | 高 (標準語法) |
| 子查詢嵌套 (TOP/ROWNUM) | 舊版本 Oracle, SQL Server | ⭐⭐ (需掃描前 N 行) | 低 |
當 OFFSET 1000000 LIMIT 10 時,數據庫需掃描並丟棄前 100 萬行,**極其低效**。
-- 假設上一頁最後一條 ID = 95000
SELECT * FROM table1 WHERE ID > 95000 ORDER BY ID LIMIT 10;
(sort_col, id)OFFSET ... FETCH** (現代版本) 或 LIMIT (MySQL/PG)ROWNUM,SQL Server 用三層 TOP