SELECT
序號 = (SELECT COUNT(客戶編號) FROM 客戶 AS L
WHERE L.客戶編號 <= C.客戶編號),
客戶編號, 公司名稱
FROM 客戶 AS C
ORDER BY 1;
每行掃描一次表,O(N²),僅適合極小資料集。
SELECT
RANK() OVER (ORDER BY 客戶編號 DESC) AS 序號,
客戶編號, 公司名稱
FROM 客戶;
相同值同序號、下一序號跳號(1,1,3)。
SELECT
序號 = COUNT(*),
L.客戶編號, L.公司名稱
FROM 客戶 AS L, 客戶 AS C
WHERE L.客戶編號 >= C.客戶編號
GROUP BY L.客戶編號, L.公司名稱
ORDER BY 序號;
同樣 O(N²),不推薦生產環境。
SELECT
序號 = IDENTITY(INT, 1, 1),
管道, 程式語言, 講師, 資歷
INTO #Tmp
FROM 問卷調查;
SELECT * FROM #Tmp;
DROP TABLE #Tmp;
需建立暫存表、寫入再讀取,有 TempDB 壓力。
WITH 排序結果 AS (
SELECT
ROW_NUMBER() OVER (ORDER BY 客戶編號 DESC) AS 序號,
客戶編號, 公司名稱
FROM 客戶
)
SELECT * FROM 排序結果
WHERE 序號 BETWEEN 2 AND 4; -- 分頁取第 2-4 筆
✅ 單掃描、✅ 無 TempDB 寫入、✅ 支援分頁、✅ 可搭配 PARTITION BY 分組編號。
| 方法 | 版本需求 | 效能 | 特性 |
|---|---|---|---|
| 子查詢 COUNT | All | ★☆☆☆☆ | 相同值連續編號 |
| RANK() | 2005+ | ★★★★☆ | 相同值同序號、跳號 |
| 自我 JOIN | All | ★☆☆☆☆ | 教學示範用 |
| IDENTITY + #Temp | 2000+ | ★★★☆☆ | 舊版相容、TempDB 壓力 |
| ROW_NUMBER() + CTE | 2005+ | ★★★★★ | 標準、分頁、分組、無副作用 |
結論:SQL Server 2005 以上環境,**首選 ROW_NUMBER() OVER() + CTE**。