ROW_NUMBER() 函數 (SQL ROW_NUMBER() Function)
ROW_NUMBER() 是一種窗口函數 (Window Function),它會為查詢結果集中的每一列指派一個連續的整數編號,編號從 1 開始。
ROW_NUMBER 語法
ROW_NUMBER() OVER (
[PARTITION BY column_name(s)]
ORDER BY column_name(s)
)
PARTITION BY: 選用,用來將結果分組,每組的編號會重新從 1 開始ORDER BY: 必填,決定編號的排列依據
ROW_NUMBER 基本用法 (Example)
假設我們有一個 employees 資料表:
| E_Id | Name | Dept | Salary |
|---|---|---|---|
| 1 | 張一 | 業務 | 50000 |
| 2 | 王二 | 研發 | 60000 |
| 3 | 李三 | 業務 | 55000 |
| 4 | 趙四 | 研發 | 70000 |
依薪資高低為每列編號:
SELECT
Name,
Salary,
ROW_NUMBER() OVER (ORDER BY Salary DESC) AS RowNum
FROM employees;
查詢結果:
| Name | Salary | RowNum |
|---|---|---|
| 趙四 | 70000 | 1 |
| 王二 | 60000 | 2 |
| 李三 | 55000 | 3 |
| 張一 | 50000 | 4 |
PARTITION BY 分組編號 (Example)
使用 PARTITION BY 可以在每個部門內分別編號:
SELECT
Name,
Dept,
Salary,
ROW_NUMBER() OVER (PARTITION BY Dept ORDER BY Salary DESC) AS DeptRank
FROM employees;
查詢結果:
| Name | Dept | Salary | DeptRank |
|---|---|---|---|
| 李三 | 業務 | 55000 | 1 |
| 張一 | 業務 | 50000 | 2 |
| 趙四 | 研發 | 70000 | 1 |
| 王二 | 研發 | 60000 | 2 |
實務應用:取各部門薪資最高的員工
SELECT Name, Dept, Salary
FROM (
SELECT
Name, Dept, Salary,
ROW_NUMBER() OVER (PARTITION BY Dept ORDER BY Salary DESC) AS rn
FROM employees
) AS ranked
WHERE rn = 1;
查詢結果:
| Name | Dept | Salary |
|---|---|---|
| 李三 | 業務 | 55000 |
| 趙四 | 研發 | 70000 |
實務應用:分頁查詢
ROW_NUMBER() 常用於實作分頁功能,例如取第 11 到 20 筆資料:
SELECT *
FROM (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY E_Id) AS rn
FROM employees
) AS numbered
WHERE rn BETWEEN 11 AND 20;
ROW_NUMBER 與 RANK、DENSE_RANK 的差異
當排序欄位有相同值時,三者的編號方式不同:
- ROW_NUMBER(): 即使值相同也會給不同編號 (1, 2, 3, 4...)
- RANK(): 相同值給相同編號,之後跳號 (1, 1, 3, 4...)
- DENSE_RANK(): 相同值給相同編號,之後不跳號 (1, 1, 2, 3...)