ranking_function OVER ([PARTITION BY partition_column_list] ORDER BY order_column_list)
SELECT 與 ORDER BY 子句中。PARTITION BY 將結果集切分為獨立分區,各分區內獨立計算排名。ORDER BY 決定排名依據,支援多欄位排序。為每列分配 1, 2, 3… 不重複編號。執行邏輯:先依 PARTITION BY 分區 → 再依 ORDER BY 排序 → 最後依序編號。
SELECT empid, qty,
ROW_NUMBER() OVER (ORDER BY qty, empid) AS rn
FROM dbo.Sales;
SELECT empid, qty,
(SELECT COUNT(*) FROM dbo.Sales S2
WHERE S2.qty < S1.qty
OR (S2.qty = S1.qty AND S2.empid <= S1.empid)) AS rn
FROM dbo.Sales S1
ORDER BY qty, empid;
相關子查詢導致 O(N²) 掃描,大資料量極慢。
SELECT empid, qty, IDENTITY(INT, 1, 1) AS rn
INTO #SalesRN FROM dbo.Sales ORDER BY qty, empid;
需額外 I/O 與暫存表管理,不如內建函數優雅高效。
假設 qty 有重複值:
| qty | ROW_NUMBER | RANK | DENSE_RANK |
|---|---|---|---|
| 100 | 1 | 1 | 1 |
| 100 | 2 | 1 | 1 |
| 90 | 3 | 3 | 2 |
| 80 | 4 | 4 | 3 |
NTILE(buckets) OVER (ORDER BY ...)
將排序後資料平均分配至 buckets 個桶,桶編號 1..N。分配規則:
CEILING(總列數 / 桶數)。餘數 個桶獲得基礎大小,其餘桶獲得 基礎大小 - 1。例:11 列分 3 桶 → 4, 4, 3。
SELECT track, speaker, score,
ROW_NUMBER() OVER (PARTITION BY track ORDER BY score DESC) AS pos_in_track
FROM SpeakerStats
ORDER BY track, pos_in_track;
各 track (DB/Dev/Sys) 獨立編號,適合「各組前 N 名」查詢。