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

SQL Server 2005 四大排序函數全解析:ROW_NUMBER、RANK、DENSE_RANK、NTILE

     編輯:關於SqlServer

前言

SQL Server 2005 引入四個 ANSI SQL 標準排序函數,徹底改變結果集排序與分組編號方式。本文以產品資料表為例,詳細比較四函數語法、行為差異與適用情境。

測試環境建立

CREATE TABLE Products (
    ProductID INT IDENTITY(1,1) PRIMARY KEY,
    Name VARCHAR(50),
    Price MONEY
)

INSERT INTO Products (Name, Price) VALUES
('產品A', 100), ('產品B', 200), ('產品C', 200),  -- 價格重複測試
('產品D', 300), ('產品E', 400), ('產品F', 500)

函數詳細比較

1. ROW_NUMBER() —— 連續唯一編號

SELECT 
    ProductID, Name, Price,
    ROW_NUMBER() OVER (ORDER BY Price DESC) AS RowNum
FROM Products
NamePriceRowNum
產品F5001
產品E4002
產品D3003
產品B2004
產品C2005
產品A1006

特性: 無視重複值,嚴格遞增 1,2,3... 最適合分頁查詢。

2. RANK() —— 競賽式排名(跳號)

SELECT 
    ProductID, Name, Price,
    RANK() OVER (ORDER BY Price DESC) AS RankNum
FROM Products
NamePriceRankNum
產品F5001
產品E4002
產品D3003
產品B2004
產品C2004
產品A1006

特性: 相同值同排名,下一名次跳過重複筆數。如奧運獎牌排名。

3. DENSE_RANK() —— 密集排名(不跳號)

SELECT 
    ProductID, Name, Price,
    DENSE_RANK() OVER (ORDER BY Price DESC) AS DenseRank
FROM Products
NamePriceDenseRank
產品F5001
產品E4002
產品D3003
產品B2004
產品C2004
產品A1005

特性: 相同值同排名,下一名次遞增 1。適合「前 N 名」不想因並列而縮減名額的情境。

4. NTILE(n) —— 等量分桶

SELECT 
    ProductID, Name, Price,
    NTILE(3) OVER (ORDER BY Price DESC) AS Bucket
FROM Products
NamePriceBucket
產品F5001
產品E4001
產品D3002
產品B2002
產品C2003
產品A1003

特性: 將排序後資料分成 n 個桶,桶編號 1~n。資料盡量均勻分配,前桶筆數 ≥ 後桶。

分頁查詢最佳實務:ROW_NUMBER() + CTE

DECLARE @PageSize INT = 10, @PageIndex INT = 3

SELECT ProductID, Name, Price
FROM (
    SELECT 
        ProductID, Name, Price,
        ROW_NUMBER() OVER (ORDER BY Price DESC) AS RowNum
    FROM Products
) AS Paged
WHERE RowNum BETWEEN (@PageIndex - 1) * @PageSize + 1 AND @PageIndex * @PageSize
ORDER BY Price DESC

PARTITION BY 進階應用:分組內排序

-- 依類別分組,各組內依價格排名
SELECT 
    Category, Name, Price,
    ROW_NUMBER() OVER (PARTITION BY Category ORDER BY Price DESC) AS RankInCategory
FROM Products

函數選擇決策樹

  • 需要連續不重複編號(分頁、匯出序號)→ ROW_NUMBER()
  • 需要競賽式排名(並列同名次、下一名次跳號)→ RANK()
  • 需要密集排名(並列同名次、下一名次不跳號)→ DENSE_RANK()
  • 需要分組統計、百分位數、四分位數→ NTILE()

效能提示

  • 四函數皆需 OVER (ORDER BY ...),確保排序欄位有索引可避免 Sort 運算子。
  • 大量資料分頁時,ROW_NUMBER() 配合 TOP 或 OFFSET/FETCH(2012+)效能最佳。
  • PARTITION BY 會增加運算複雜度,僅在必要時使用。

結語

四大排序函數各有專精領域。ROW_NUMBER() 是分頁王者;RANK()/DENSE_RANK() 解決商業排名報表需求;NTILE() 則是資料分析分組利器。熟練掌握這四把刷子,T-SQL 表達力將大幅提升。

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