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

SQL Server 與 Oracle 分頁查詢深度對比:算法變數、ROWNUM/CTE/TOP 三大流派完整實戰

     編輯:關於SqlServer

分頁通用算法變數

變數含義來源
pageSize每頁筆數使用者輸入 / 系統配置
pageNow當前頁碼 (1-based)使用者輸入
totalRecords總筆數`SELECT COUNT(*) FROM table`
totalPages總頁數`CEILING(totalRecords / pageSize)`
beginRow起始行號`(pageNow-1)*pageSize + 1`
endRow結束行號`pageNow*pageSize`

Oracle 三步驟 ROWNUM 模板 (經典、全版本相容)

-- 以 EMP 表為例,每頁 5 筆,查第 2 頁 (第 6-10 筆)
SELECT * FROM (
    SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM emp ORDER BY empno  -- 1. 內層:基礎排序查詢
    ) a
    WHERE ROWNUM <= 10                   -- 2. 中層:截取前 endRow 筆
) WHERE rn >= 6;                         -- 3. 外層:過濾 beginRow 之後

參數化模板

SELECT * FROM (
    SELECT a.*, ROWNUM rn FROM (
        SELECT * FROM ${table} ${where} ORDER BY ${orderCol}
    ) a
    WHERE ROWNUM <= :endRow
) WHERE rn >= :beginRow;
  • 只需修改**最內層**查詢 (欄位、條件、排序),外層邏輯固定。
  • Oracle 12c+ 可直接用 `OFFSET :offset ROWS FETCH NEXT :limit ROWS ONLY`。

SQL Server 三大流派

流派一:巢狀 TOP + 反向排序 (SQL 2000+ 通用)

SELECT TOP (@pageSize) *
FROM (
    SELECT TOP (@pageSize * @pageNow) *
    FROM emp
    ORDER BY empid ASC
) t
ORDER BY empid DESC;
  • 內層 `ASC` 取前 N 筆,外層 `DESC` 取最後 pageSize 筆,再隱含反轉順序 (或外層再包一層 `ASC`)。
  • 參數化:`@pageSize`、 `@pageNow`。

流派二:TOP + IN 子查詢

SELECT TOP (@pageSize) *
FROM emp
WHERE empid IN (
    SELECT TOP (@pageSize * @pageNow) empid
    FROM emp
    ORDER BY empid
)
ORDER BY empid DESC;
  • 邏輯同流派一,寫法不同,執行計畫通常相同。

流派三:ROW_NUMBER() / OFFSET-FETCH (現代標準)

-- SQL 2005+ ROW_NUMBER()
WITH CTE AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY empid) AS RN FROM emp
)
SELECT * FROM CTE WHERE RN BETWEEN (@pageNow-1)*@pageSize+1 AND @pageNow*@pageSize;

-- SQL 2012+ OFFSET-FETCH (最簡潔)
SELECT * FROM emp
ORDER BY empid
OFFSET (@pageNow-1)*@pageSize ROWS FETCH NEXT @pageSize ROWS ONLY;

效能與選型建議

資料庫推薦寫法版本要求備註
Oracle`OFFSET-FETCH`12c+標準 SQL,最優
Oracle三層 ROWNUMAll舊版唯一選擇
SQL Server`OFFSET-FETCH`2012+原生、簡潔、效能最佳
SQL Server`ROW_NUMBER()` CTE2005+舊版標準
SQL Server巢狀 TOP2000+極舊版備用

深分頁優化 (共通)

  1. 延遲關聯:內層只查 PK,外層 `JOIN` 回表。
  2. 游標式分頁:前端傳 `last_id`,`WHERE id > @last_id ORDER BY id LIMIT @pageSize` (需唯一遞增鍵)。
  3. 覆蓋索引:`INCLUDE` 所有 `SELECT` 欄位,避免書籤查找。

總結

**分頁核心變數六個**,Oracle 用 `ROWNUM` 三層包裹或 `OFFSET-FETCH`,SQL Server 用 `OFFSET-FETCH` / `ROW_NUMBER()`。深分頁**延遲關聯**通吃兩庫。新專案**強制使用標準 `OFFSET-FETCH`**,舊版才退而求其次。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved