需求:依欄位 A 分組,組內依欄位 B 降序排列,取每組前 3 筆資料。Oracle 12c+ 可用 FETCH FIRST,但通用寫法仍是窗口函數 ROW_NUMBER()。
SELECT *
FROM (
SELECT T.B,
T.A,
ROW_NUMBER() OVER (PARTITION BY T.A ORDER BY T.B DESC) AS RN
FROM YOUR_TABLE T
)
WHERE RN <= 3;
PARTITION BY T.A:依 A 分組,各組獨立計算行號ORDER BY T.B DESC:組內按 B 降序,最大值行號為 1ROW_NUMBER():生成 1,2,3... 不重複行號(同序值也強制區分)WHERE RN <= 3:過濾取前 3 名| 需求 | 函數選擇 | 差異 |
|---|---|---|
| 允許同序並列 | RANK() | 同分同名次,下一名次跳號(1,1,3) |
| 同序並列且不跳號 | DENSE_RANK() | 同分同名次,下一名次不跳(1,1,2) |
| 分頁查詢 | ROW_NUMBER() | 配合 BETWEEN 實現精確分頁 |
(A, B) 上有索引,支援 PARTITION BY ... ORDER BY 的排序消除SELECT * FROM T ORDER BY A, B DESC FETCH FIRST 3 ROWS PER GROUP(需 12.1.0.2+)此模式廣泛應用於:各部門薪資前三、各類別熱銷商品、各用戶最近登入記錄等場景,是 Oracle 開發必備技能。