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

T-SQL 排名函數完整教學:TOP WITH TIES、視圖法、暫存表法、游標法與三種並列處理規則

     編輯:關於SqlServer

排名需求常見於排行榜、分頁、Top-N 分析。本文系統介紹五種 T-SQL 排名實作,並深入解析「並列 (Tie)」的三種處理規則。

基礎:TOP n WITH TIES

SELECT TOP 5 WITH TIES title_id, price, title_name
FROM title
ORDER BY price DESC;

價格並列者全部顯示,可能超過 5 筆 (範例返回 8 筆)。

方法一:標準 SQL 相關子查詢 (視圖/衍生表)

CREATE VIEW ranked_sales AS
SELECT 
    (SELECT COUNT(DISTINCT T2.price) FROM title T2 WHERE T2.price >= T1.price) AS rank,
    title_id, price, title_name
FROM title T1 WHERE price IS NOT NULL;
  • 符合 ANSI SQL,可移植
  • 效能差:每列掃描一次外部表,大表不可用

方法二:衍生表 (Inline View) — 效能同方法一

SELECT rank, title_id, price, title_name
FROM (
    SELECT T1.title_id, T1.price, T1.title_name,
           (SELECT COUNT(DISTINCT T2.price) FROM title T2 WHERE T1.price <= T2.price) AS rank
    FROM title T1
) X
WHERE price IS NOT NULL
ORDER BY rank;

方法三:暫存表 + IDENTITY (無並列處理)

CREATE TABLE #ranked (rank int IDENTITY PRIMARY KEY, title_id char(6), price int, title_name varchar(30));
INSERT #ranked SELECT title_id, price, title_name FROM title WHERE price IS NOT NULL ORDER BY price DESC;
SELECT * FROM #ranked;
  • 速度快,單次掃描
  • 並列項獲得連續不同排名 (1,2,3,4,5,6,7,8…)

方法四:暫存表 + 分組最小排名 (支援並列,規則 3)


CREATE TABLE #ranked (rank int IDENTITY, title_id char(6), price int, title_name varchar(30));
INSERT #ranked SELECT title_id, price, title_name FROM title WHERE price IS NOT NULL ORDER BY price DESC;

SELECT B.rank, A.title_id, B.price, A.title_name
FROM (
    SELECT MIN(T2.rank) AS rank, T2.price
    FROM #ranked T2 GROUP BY T2.price
) B, #ranked A
WHERE A.price = B.price
ORDER BY B.rank;

並列項共享最小排名 (1,2,3,4,5,5,5,5,9…),下一名跳躍 (Gap),符合 **Olympic/競賽排名 (規則 3)**。

進階:顯式標示並列狀態


SELECT B.rank,
       CASE B.number_tied WHEN 1 THEN '' ELSE '(' + CAST(B.number_tied AS varchar) + ' Way TIE)' END AS tie,
       A.title_id, B.price, A.title_name
FROM (
    SELECT MIN(T2.rank) AS rank, COUNT(*) AS number_tied, T2.price
    FROM #ranked T2 GROUP BY T2.price
) B, #ranked A
WHERE A.price = B.price
ORDER BY B.rank;

方法五:游標法 (單次掃描,適合時序運算)

三種並列規則對應三個游標實作:

程式碼結構:宣告游標 → ORDER BY 排序鍵 → FETCH 迴圈 → 變數追蹤 @last_price、@last_rank、@counter → 依規則計算排名 → 輸出。

效能與選擇建議

規則定義排名序列範例
規則 1並列同排名,下一名遞增 11,2,3,4,5,5,5,5,6…
規則 2每列唯一排名 (忽略並列)1,2,3,4,5,6,7,8,9…
規則 3並列同排名,下一名依實際位置 (Gap)1,2,3,4,5,5,5,5,9…
方法適用場景並列支援效能
視圖/衍生表小表、教學、跨平台規則 3慢 (N²)
暫存表 + IDENTITY大表、不需並列語意無快
暫存表 + 分組大表、需 Olympic 排名規則 3快
游標複雜時序邏輯、逐列運算三種皆可中 (慢於暫存表)
SQL 2005+ 視窗函數現代首選RANK/DENSE_RANK/ROW_NUMBER最佳

現代專案請直接使用 RANK() (規則 3)、DENSE_RANK() (規則 1)、ROW_NUMBER() (規則 2),語法簡潔、最佳化器支援最完善。本文保留傳統寫法供維護舊系統參考。

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