最近在用Oracle的ROWNUM的時候,發現生成的值是亂的,不是自己期望的“連續遞增”順序值

SELECT 
	ROWNUM,
	username
FROM USER
ORDER BY ID ASC;

百度之後才瞭解到是對ROWNUM的理解不夠,用法不對

ROWNUM 是在查詢結果生成前分配的,它不隨 ORDER BY 而變化。

因為我的SQL裏面用到了ORDER BY排序,我期望ROWNUM可以根據我想要的排序進行生成連續的值

ROWNUM具體過程如下:

  1. Oracle 先執行 FROM 和 WHERE,篩選出符合條件的數據。
  2. 然後 立即為每行分配一個 ROWNUM 值(從 1 開始),此時還沒有執行 ORDER BY
  3. 最後才執行 ORDER BY,對結果排序。

⚠️ 所以:
👉 ROWNUM 是根據 原始查詢結果的物理順序 分配的,而不是按照 ORDER BY 後的邏輯順序!

這意味着即使你加了 ORDER BYROWNUM 仍然可能是亂序的。

那怎麼才能達到期望的效果呢???

✅ 正確做法:使用 ROW_NUMBER() 分析函數

SELECT 
	ROW_NUMBER() OVER (ORDER BY ID ASC) AS ROWNUM,
	username
FROM USER;

ROWNUM vs ROW_NUMBER()

特性

ROWNUM

ROW_NUMBER()

是否支持 ORDER BY

❌ 不支持(影響 ROWNUM 分配)

✅ 支持,且可配合 OVER() 使用

用途

快速限制返回行數(如 ROWNUM <= 10

按邏輯順序編號(常用於分頁、排名等)

是否可排序後編號

❌ 不行

✅ 可以

補充説明

  • ROWNUM 是偽列,用於限制返回行數(如分頁),不能用於生成排序後的序號
  • 如果你確實需要先排序再編號,必須用 ROW_NUMBER()RANK(), 或 DENSE_RANK() 等分析函數。