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

SQL Server 2005 利用 ROW_NUMBER() OVER 實作高效分頁查詢

     編輯:SQL Server 2005

SQL Server 2005 引入視窗函數 ROW_NUMBER() OVER,提供比舊版 TOP ... NOT IN 或游標更優雅、效能更好的分頁解決方案。本文從基本語法到實戰分頁範例完整說明。

ROW_NUMBER() OVER 基本語法

ROW_NUMBER() OVER (PARTITION BY 分群欄位 ORDER BY 排序欄位) AS RowNum
  • PARTITION BY:選擇性,依欄位分群,各群內部編號從 1 開始。
  • ORDER BY:必要,決定編號順序。

範例資料

CREATE TABLE Employee (EmpID INT, DeptID INT, Salary DECIMAL(10,2));
INSERT INTO Employee VALUES
(1,10,5500), (2,10,4500), (3,20,1900), (4,20,4800),
(5,40,6500), (6,40,14500), (7,40,44500), (8,50,6500), (9,50,7500);

分群編號展示

SELECT
    EmpID, DeptID, Salary,
    ROW_NUMBER() OVER (PARTITION BY DeptID ORDER BY Salary DESC) AS RankInDept
FROM Employee;
/*
EmpID DeptID Salary RankInDept
7     40     44500  1
6     40     14500  2
5     40     6500   3
...
*/

簡易分頁實作 (每頁 5 筆)

-- 將編號結果作為衍生表
WITH Numbered AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY Salary DESC) AS RowNum
    FROM Employee
)
SELECT * FROM Numbered WHERE RowNum BETWEEN 1 AND 5;  -- 第 1 頁
SELECT * FROM Numbered WHERE RowNum BETWEEN 6 AND 10; -- 第 2 頁

通用分頁範本 (參數化)

DECLARE @PageSize INT = 20, @PageNum INT = 3;

WITH Numbered AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY SomeColumn) AS RowNum
    FROM YourTable
    WHERE SomeCondition = 1
)
SELECT * FROM Numbered
WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1 AND @PageNum * @PageSize
ORDER BY RowNum;

多表聯查分頁

同樣原理,將聯查結果包在 CTE 中編號再分頁:

WITH Numbered AS (
    SELECT
        o.OrderID, c.CustomerName, o.OrderDate, o.TotalAmount,
        ROW_NUMBER() OVER (ORDER BY o.OrderDate DESC) AS RowNum
    FROM Orders o
    INNER JOIN Customers c ON c.CustomerID = o.CustomerID
    WHERE o.Status = 'Completed'
)
SELECT * FROM Numbered
WHERE RowNum BETWEEN 21 AND 40; -- 第 2 頁,每頁 20 筆

效能優化建議

  • 索引支援 ORDER BY:OVER (ORDER BY ...) 依賴排序,確保排序欄位有索引 (含覆蓋索引) 避免 Sort 運算子。
  • 避免 SELECT *:僅選取必要欄位,減少資料傳輸與排序成本。
  • 大資料量改用 Keyset Pagination:百萬列以上,ROW_NUMBER 需全量排序,改用 WHERE Key > @LastKey ORDER BY Key LIMIT @PageSize (SQL 2012+ OFFSET/FETCH)。
  • 統計資料更新:確保查詢最佳化器有正確基數估計,選擇最佳執行計畫。

版本演進

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
版本分頁語法特點
SQL 2000TOP + NOT IN / 暫存表效能差、語法繁瑣
SQL 2005/2008/R2ROW_NUMBER() OVER + CTE標準視窗函數、廣泛支援
SQL 2012+OFFSET @Rows FETCH NEXT @Rows ROWS ONLYANSI 標準、語法簡潔、計畫穩定