2011-07-21 56 views
2
SELECT id 
     FROM ( 
SELECT id 
     FROM table  
     WHERE 
     PROCS_DT is null 
     ORDER BY prty desc, cret_dt) where rownum >0 and rownum <=100 

上面的查詢是給我回100個記錄如預期甲骨文選擇查詢的幫助,請

SELECT id 
      FROM ( 
    SELECT id 
      FROM table  
      WHERE 
      PROCS_DT is null 
      ORDER BY prty desc, cret_dt) where rownum >101 and rownum <=200 

爲什麼上面的查詢返回我零記錄?

有人能幫助我如何繼續。我在Oracle啞......

+0

你確定子查詢中有超過100行嗎? –

+0

子查詢是選擇*其中拉10k行 – Shiv

回答

3

試試這個:

SELECT id 
FROM 
    (SELECT id, 
      rownum AS rn 
    FROM 
    (SELECT id 
     FROM TABLE 
     WHERE PROCS_DT IS NULL 
     ORDER BY prty DESC, cret_dt)) 
WHERE rn >101 
    AND rn <=200 

如果您習慣使用分析功能,試試這個:

SELECT id 
    FROM 
    (
     SELECT id, 
       ROW_NUMBER() OVER(ORDER BY prty DESC, cret_dt) rn 
      FROM table 
     WHERE procs_dt IS NULL 
    ) 
WHERE rn >101 and rn <=200 
+0

它不會給ID爲101-200您可以檢查您的數據庫中...(這是不是先前訂購)...你必須採取中間查詢也與你必須應用rounum alise .. –

+0

@Pratik:你指哪個查詢? – Chandu

+0

對不起,但我說的是任何錯誤.. 就在2周前我試圖得到這種或行 並沒有得到與這種相同的查詢 –

3

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」的結果集的一部分返回。這允許最外層過濾該值以建立下限。

我會試驗這個變體和分析函數,看看哪個在你的情況下表現更好。

+0

+1爲描述爲什麼返回的ROWNUM值始終始於1,最後一行 –