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

SQL Server 排名函數 DENSE_RANK 實戰:並列名次 Top N 查詢最佳解法

     編輯:關於SqlServer

需求:查詢「成績前 5 名學生」,但成績可並列 (如 3 人同分 99 分),使用 `ROW_NUMBER()` 會強制打散名次,導致前 5 名可能遺漏並列同分者。`DENSE_RANK()` 完美解決:並列同分、名次不跳號、直接篩選 `rank <= 5`。

測試資料

DECLARE @t TABLE (ID INT, StudentName NVARCHAR(15), Score INT);
INSERT INTO @t VALUES
(1,'黃一',99),(2,'吳二',99),(3,'張三',99),
(4,'李四',98),(5,'王五',97),(6,'趙六',96),
(7,'田七',95),(8,'紀八',94),(9,'邱九',93),(10,'林十',92);

方案一:傳統 DISTINCT + JOIN (繁瑣)

SELECT t1.* 
FROM @t t1
JOIN (SELECT DISTINCT TOP 5 Score FROM @t ORDER BY Score DESC) t2
  ON t1.Score = t2.Score
ORDER BY t1.Score DESC;

缺點:需額外排序、JOIN 開銷、程式碼冗長。

方案二:DENSE_RANK() 一行搞定 (推薦)

WITH cte AS (
    SELECT 
        DENSE_RANK() OVER (ORDER BY Score DESC) AS Rank,
        *
    FROM @t
)
SELECT * FROM cte WHERE Rank <= 5;

結果: 3 位 99 分同為 Rank 1、98 分 Rank 2、97 分 Rank 3、96 分 Rank 4、95 分 Rank 5 → 共 7 筆資料,完美符合「前 5 名含並列」語意。

原始資料

DENSE_RANK 結果

延伸:RANK() vs DENSE_RANK() 差異

同樣資料改用 `RANK()`:

SELECT RANK() OVER (ORDER BY Score DESC) AS Rank, * FROM @t;
  • 99 分 (3 人) → Rank 1, 1, 1
  • 98 分 → Rank 4 (跳過 2, 3)
  • 97 分 → Rank 5
  • 96 分 → Rank 6

`RANK()` 適合「競賽名次」語意 (並列佔用名次);`DENSE_RANK()` 適合「分級/分頁/Top N 含並列」語意。

RANK 結果

適用場景速查

函數並列處理名次連續性典型用途
ROW_NUMBER()強制打散 (依次序)1,2,3,4... 無間隙分頁、去重、唯一排序
RANK()同分同名次有間隙 (1,1,1,4,5...)競賽排名、銷售冠軍
DENSE_RANK()同分同名次無間隙 (1,1,1,2,3...)Top N 含並列、等級分級
NTILE(n)平均分桶1..n 循環分位數、百分位分組

掌握四大排名函數特性,即可用最簡潔 SQL 解決複雜排序分級需求。

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