ROWNUM值分配給行,因爲它們是從查詢(或子查詢)返回。如果一行沒有被返回,它根本沒有被分配一個ROWNUM值;所以返回的ROWNUM值總是從1開始,並且每行增加1。
(請注意,這些值之前,由ORDER BY
條款有何排序顯示分配的。這就是爲什麼你的情況,你需要檢查ROWNUM的子查詢外)。
你有邏輯的奇數位瞭解當你在ROWNUM上有一個謂詞時,你正在過濾一個只有當行通過過濾器時才存在的值。從概念上講,Oracle首先在查詢中應用任何其他過濾器,然後暫時將ROWNUM 1分配給第一個匹配行,並根據ROWNUM上的過濾器進行檢查。如果它通過了這個檢查,它將以該ROWNUM值返回,並且下一行將暫時分配給ROWNUM 2.但是如果它沒有通過檢查,則該行被丟棄,並且同樣的ROWNUM值暫時分配給下一行。
因此,如果ROWNUM上的過濾器不接受值1,則不會有行通過過濾器。
在其他答案中顯示的分析函數ROW_NUMBER()
的使用是解決此問題的一種方法。該函數根據給定的順序顯式地分配行號(與ROWNUM不同)。但是,這可能會顯着改變性能,因爲優化程序不一定意識到它可以避免將數字分配到可能的行以完成查詢。
做你想要什麼的傳統的基於ROWNUM,方法是:
SELECT id
FROM (
SELECT rownum rn, id
FROM (
SELECT id
FROM table
WHERE
PROCS_DT is null
ORDER BY prty desc, cret_dt
) where rownum <=200
) where rn > 101
的最內層查詢概念查找所有匹配的行和排序。下一層將ROWNUM分配給這些並僅返回前200個匹配項。 (實際上,Oracle優化器理解ROWNUM過濾器之後的排序的重要性,並且通常會按照識別最高200行的方式進行排序,而不必關心其他行的特定排序。)
中間層也使用它指定的ROWNUM並將它們作爲其別名爲「rn」的結果集的一部分返回。這允許最外層過濾該值以建立下限。
我會試驗這個變體和分析函數,看看哪個在你的情況下表現更好。
你確定子查詢中有超過100行嗎? –
子查詢是選擇*其中拉10k行 – Shiv