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

SQL Server 分頁查詢四大寫法完整比較(含 OFFSET/FETCH 最佳實踐)

     編輯:關於SqlServer

分頁是應用開發核心需求。SQL Server 歷經多版本演進,提供多種分頁寫法。本文以「每頁 10 筆、查第 2 頁」為例,比較四種主流寫法,重點解析 SQL Server 2012+ 引入的標準 OFFSET/FETCH 語法優勢與用法細節。

測試情境

資料表:dbo.Message,主鍵 Code,建立時間 CreateTime。需求:每頁 10 筆,取得第 2 頁(第 11-20 筆)。

四種寫法比較

1. 雙重 TOP + NOT IN(舊版相容,效能較差)

SELECT TOP(20) *
FROM dbo.Message
WHERE Code NOT IN (SELECT TOP(10) Code FROM dbo.Message);
  • 缺點:需排序兩次,NOT IN 遇 NULL 值有陷阱,大資料量效能差。

2. 暫存表 + ROW_NUMBER() + BETWEEN

SELECT *, ROW_NUMBER() OVER(ORDER BY Code) AS rowNum INTO #a FROM dbo.Message;
SELECT * FROM #a WHERE rowNum BETWEEN 11 AND 20;
DROP TABLE #a;
  • 缺點:建立/刪除暫存表額外開銷,佔用 tempdb。

3. CTE + ROW_NUMBER() + BETWEEN(SQL 2005+ 主流寫法)

WITH sss AS (
    SELECT *, ROW_NUMBER() OVER(ORDER BY CreateTime) AS rowNum FROM DBO.Message
)
SELECT * FROM sss WHERE rowNum BETWEEN 11 AND 20;
  • 優點:語法清晰、無暫存表、支援複雜排序,為 2005-2008 R2 版本最佳選擇。

4. OFFSET/FETCH(SQL Server 2012+ 標準語法,推薦)

SELECT * FROM DBO.Message
ORDER BY CreateTime
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

OFFSET/FETCH 深度解析

屬於 ORDER BY 子句一部分,符合 ANSI SQL 標準,支援跳過功能,專為分頁設計。

語法結構

ORDER BY <排序欄位>
OFFSET <跳過筆數> {ROW | ROWS}
[FETCH {FIRST | NEXT} <取得筆數> {ROW | ROWS} ONLY]

關鍵特性

  • 必須搭配 ORDER BY,確保結果確定性。
  • ROW/ROWS、FIRST/NEXT 可互換,提升可讀性(如 FETCH 1 ROW、OFFSET 0 ROWS)。
  • 可單獨使用 OFFSET 跳過 N 筆並取得剩餘所有資料。
  • 不支援 PERCENT 與 WITH TIES 選項(TOP 支援)。

實戰範例

-- 取得第 3 頁,每頁 25 筆,依訂單日期、ID 排序
SELECT orderid, orderdate, custid, empid
FROM Sales.Orders
ORDER BY orderdate, orderid
OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY;

選擇建議

版本推薦寫法備註
SQL 2000/2005/2008/R2CTE + ROW_NUMBER()相容性最好,效能穩定
SQL 2012+OFFSET/FETCH標準語法、可讀性最佳、計畫重用率高
需 TOP PERCENT/WITH TIESTOPOFFSET/FETCH 不支援

結論:現代專案優先採用 OFFSET/FETCH,舊版維護專案使用 CTE 寫法。

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