首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 教學

主流資料庫分頁查詢語法大全:Oracle、MySQL、SQL Server、PostgreSQL、DB2

     編輯:Oracle 教學

五大資料庫分頁語法對照表

資料庫分頁語法參數說明
MySQLSELECT ... LIMIT offset, rowsoffset 從 0 起;rows 為頁大小
PostgreSQLSELECT ... LIMIT rows OFFSET offset同 MySQL,語序不同
Oracle三層嵌套 ROWNUM 或 12c+ OFFSET ... FETCH見下文詳細範例
SQL Server2012+ OFFSET ... FETCH;舊版 TOP + NOT IN/游標見下文
DB2SELECT ... FROM (SELECT ROW_NUMBER() OVER(...) AS rn, t.* FROM t) WHERE rn BETWEEN ? AND ?標準窗口函數
InterBaseSELECT ... ROW start TO end專有語法

Oracle 分頁演進與最佳實踐

經典三層 ROWNUM 寫法 (全版本通用)

SELECT * FROM (
    SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM emp ORDER BY sal DESC
    ) a WHERE ROWNUM <= 40
) WHERE rn > 21;

原理:內層排序 → 中層截取前 N 行 (STOPKEY 優化) → 外層過濾起始行。
優勢:中層 ROWNUM <= :max_row 觸發 COUNT STOPKEY,避免全表掃描。

12c 簡潔語法

SELECT * FROM emp ORDER BY sal DESC
OFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY;

窗口函數寫法 (10g+,適合複雜排序)

SELECT * FROM (
    SELECT t.*, ROW_NUMBER() OVER (ORDER BY sal DESC) rn FROM emp t
) WHERE rn BETWEEN 21 AND 40;

MySQL 分頁優化

-- 基礎
SELECT * FROM t_order LIMIT 5, 10;  -- 第 6-15 行

-- 百萬級深分頁優化:子查詢定位主鍵再回表
SELECT * FROM t_order
WHERE id >= (SELECT id FROM t_order ORDER BY id LIMIT 490000, 1)
LIMIT 10;

SQL Server 分頁方案對比

方案適用版本語法效率
TOP + NOT IN2000+SELECT TOP 10 * FROM t WHERE id NOT IN (SELECT TOP 20 id FROM t ORDER BY id) ORDER BY id中
TOP + MAX(id)2000+SELECT TOP 10 * FROM t WHERE id > (SELECT MAX(id) FROM (SELECT TOP 20 id FROM t ORDER BY id) a) ORDER BY id高 (需主鍵索引)
ROW_NUMBER()2005+SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY id) rn, * FROM t) a WHERE rn > 20 AND rn <= 30高,標準寫法
OFFSET/FETCH2012+SELECT * FROM t ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY最佳,原生優化
游標/存儲過程所有sp_cursoropen/fetch/close低,通用但資源消耗大

Oracle 分頁進階:Hint 與連接優化

多表分頁時,加 /*+ FIRST_ROWS */ 引導優化器選擇 NESTED LOOP,避免 HASH JOIN 全量處理:

SELECT /*+ FIRST_ROWS */ * FROM (
    SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM t1 JOIN t2 ON ... WHERE ...
    ) a WHERE ROWNUM <= :max
) WHERE rn > :min;

實戰案例:三種 ROWNUM 分頁對比

-- 1. rowid 定位 (適合大表、無序)
SELECT * FROM passvehicleinfo p
WHERE rowid IN (
  SELECT rid FROM (
    SELECT rownum rn, rid FROM (
      SELECT p.rowid rid FROM passvehicleinfo p ORDER BY p.passvehicleid DESC
    ) WHERE rownum < 10000
  ) WHERE rn > 9980
) ORDER BY p.passvehicleid ASC;

-- 2. ROW_NUMBER() 窗口函數 (10g+,可讀性佳)
SELECT * FROM (
  SELECT p.*, ROW_NUMBER() OVER (ORDER BY p.passvehicleid DESC) rk
  FROM passvehicleinfo p
) WHERE rk > 9980 AND rk < 10000;

-- 3. 經典 ROWNUM 三層嵌套 (最通用)
SELECT * FROM (
  SELECT view1.*, ROWNUM rn FROM (
    SELECT p.* FROM passvehicleinfo p ORDER BY p.passvehicleid DESC
  ) view1 WHERE ROWNUM < 10000
) view2 WHERE rn > 9980;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved