基本語法
SELECT * FROM (
SELECT ROW_NUMBER() OVER (ORDER BY CreateTime DESC) AS RowNumber, *
FROM dbo.TableName
) t
WHERE RowNumber BETWEEN 1 AND 5;
完整分頁範本
DECLARE @PageIndex INT = 2, @PageSize INT = 10;
SELECT * FROM (
SELECT ROW_NUMBER() OVER (ORDER BY Id) AS rn, *
FROM dbo.BigTable
) t
WHERE rn BETWEEN (@PageIndex-1)*@PageSize+1 AND @PageIndex*@PageSize
ORDER BY rn;
三種常見寫法比較
| 寫法 | 優點 | 缺點 |
| NOT IN + TOP | 相容 SQL 2000 | 需主鍵連續遞增,效能差 |
| ROW_NUMBER() + CTE | 語法清晰、支援任意排序 | 需 SQL 2005+ |
| OFFSET/FETCH (2012+) | ANSI 標準、最簡潔 | 版本限制 |
注意事項
- 外層查詢不可直接使用
RowNumber 排序,需在內層 ORDER BY 完成。
- 大資料量建議加上覆蓋索引避免 Key Lookup。
- 搭配
OPTION (RECOMPILE) 解決參數嗅探導致計畫不穩。