使用語法
ROW_NUMBER() OVER ([PARTITION BY partition_column1, partition_column2, ...]ORDER BY sort_column1 [ASC|DESC], sort_column2 [ASC|DESC], ...
)
- PARTITION BY:將數據按指定列分組,每組內單獨生成行號。
- ORDER BY:決定組內行號的排序依據。
適用場景
1. 分頁查詢
在需要對結果集分頁且需要全局排序時,ROW_NUMBER() 可替代傳統 LIMIT/OFFSET,尤其在復雜排序或嵌套查詢中更高效。
SELECT *
FROM (SELECT ROW_NUMBER() OVER (ORDER BY create_time DESC) AS row_num,id, title, create_timeFROM articles
) AS tmp
WHERE row_num BETWEEN 11 AND 20; -- 獲取第2頁(每頁10條)
2. 去重(保留每組最新/第一條記錄)
當數據有重復時,按業務邏輯保留每組中的特定行(如最新記錄)。
WITH ranked_data AS (SELECT id, user_id, order_date,ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date DESC) AS rnFROM orders
)
SELECT id, user_id, order_date
FROM ranked_data
WHERE rn = 1; -- 每個用戶最近的一筆訂單
3. 生成唯一排名(無并列排名)
即使值相同,ROW_NUMBER() 也會生成唯一序號(區別于 RANK() 和 DENSE_RANK())。
SELECT student_id, exam_score,ROW_NUMBER() OVER (ORDER BY exam_score DESC) AS rank
FROM exam_results; -- 分數相同的學生會得到不同排名
4. 分組分析(如時間序列處理)
按分區跟蹤行號,用于分析組內趨勢(如計算用戶行為序列
SELECT user_id, event_time, event_type,ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY event_time) AS action_seq
FROM user_events; -- 標記用戶行為的順序
注意事項:
去重替代方案:若僅需去重,可考慮 DISTINCT 或 GROUP BY,但復雜邏輯仍需 ROW_NUMBER()。