最近在用Oracle的ROWNUM的時候,發現生成的值是亂的,不是自己期望的“連續遞增”順序值
SELECT
ROWNUM,
username
FROM USER
ORDER BY ID ASC;
百度之後才瞭解到是對ROWNUM的理解不夠,用法不對
ROWNUM 是在查詢結果生成前分配的,它不隨 ORDER BY 而變化。
因為我的SQL裏面用到了ORDER BY排序,我期望ROWNUM可以根據我想要的排序進行生成連續的值
ROWNUM具體過程如下:
- Oracle 先執行
FROM和WHERE,篩選出符合條件的數據。 - 然後 立即為每行分配一個
ROWNUM值(從 1 開始),此時還沒有執行ORDER BY。 - 最後才執行
ORDER BY,對結果排序。
⚠️ 所以:
👉 ROWNUM 是根據 原始查詢結果的物理順序 分配的,而不是按照 ORDER BY 後的邏輯順序!
這意味着即使你加了 ORDER BY,ROWNUM 仍然可能是亂序的。
那怎麼才能達到期望的效果呢???
✅ 正確做法:使用 ROW_NUMBER() 分析函數
SELECT
ROW_NUMBER() OVER (ORDER BY ID ASC) AS ROWNUM,
username
FROM USER;
ROWNUM vs ROW_NUMBER()
|
特性
|
|
|
|
是否支持 |
❌ 不支持(影響 |
✅ 支持,且可配合 |
|
用途
|
快速限制返回行數(如 |
按邏輯順序編號(常用於分頁、排名等)
|
|
是否可排序後編號
|
❌ 不行
|
✅ 可以
|
補充説明
ROWNUM是偽列,用於限制返回行數(如分頁),不能用於生成排序後的序號。- 如果你確實需要先排序再編號,必須用
ROW_NUMBER(),RANK(), 或DENSE_RANK()等分析函數。