SQL Server 2005 引入四個排名視窗函數,廣泛應用於分頁、排行榜、分組排序、資料分桶等場景。本文透過實例詳細解析其差異與適用場景。
CREATE TABLE Sales (
empid VARCHAR(10) PRIMARY KEY,
mgrid VARCHAR(10),
qty INT
)
INSERT Sales VALUES
('A','Z',300), ('B','X',100), ('C','X',200), ('D','Y',200),
('E','Z',250), ('F','Z',300), ('G','X',100), ('H','Y',150),
('I','X',250), ('J','Z',100), ('K','Y',200)
CREATE INDEX idx_qty_empid ON Sales(qty, empid)
CREATE INDEX idx_mgrid_qty_empid ON Sales(mgrid, qty, empid)
SELECT empid, qty,
ROW_NUMBER() OVER (ORDER BY qty) AS RowNum
FROM Sales ORDER BY qty
ORDER BY 欄位是否重複,皆產生 1,2,3... 連續不重複序號。ORDER BY 應包含唯一鍵(如 qty, empid)。PARTITION BY 分組計算。SELECT empid, qty,
RANK() OVER (ORDER BY qty) AS rnk
FROM Sales ORDER BY qty
SELECT empid, qty,
DENSE_RANK() OVER (ORDER BY qty) AS drnk
FROM Sales ORDER BY qty
SELECT empid, qty,
NTILE(3) OVER (ORDER BY qty, empid) AS bucket
FROM Sales ORDER BY qty, empid
SELECT empid, qty,
ROW_NUMBER() OVER (ORDER BY qty) AS rn,
RANK() OVER (ORDER BY qty) AS rk,
DENSE_RANK() OVER (ORDER BY qty) AS drk,
NTILE(4) OVER (ORDER BY qty) AS nt
FROM Sales ORDER BY qty
輸出片段(qty 由小到大):
| empid | qty | rn | rk | drk | nt |
|---|---|---|---|---|---|
| B | 100 | 1 | 1 | 1 | 1 |
| G | 100 | 2 | 1 | 1 | 1 |
| J | 100 | 3 | 1 | 1 | 1 |
| H | 150 | 4 | 4 | 2 | 1 |
| C | 200 | 5 | 5 | 3 | 2 |
| D | 200 | 6 | 5 | 3 | 2 |
| K | 200 | 7 | 5 | 3 | 2 |
| I | 250 | 8 | 8 | 4 | 3 |
| E | 250 | 9 | 8 | 4 | 3 |
| A | 300 | 10 | 10 | 5 | 4 |
| F | 300 | 11 | 10 | 5 | 4 |
SELECT mgrid, empid, qty,
ROW_NUMBER() OVER (PARTITION BY mgrid ORDER BY qty, empid) AS RowNum
FROM Sales ORDER BY mgrid, qty
每個 mgrid 群組內獨立計算序號,適用於「各部門前 N 名」等需求。
PARTITION BY 欄位, ORDER BY 欄位(含覆蓋欄位)。TOP 限制範圍。-- 相關子查詢法(效能差,O(N^2))
SELECT empid, (SELECT COUNT(*) FROM Sales s2 WHERE s2.empid <= s1.empid) AS rn
FROM Sales s1 ORDER BY empid
-- IDENTITY 插入暫存表法
SELECT empid, qty, IDENTITY(int,1,1) AS rn INTO #tmp FROM Sales ORDER BY qty