2012-05-30 14 views
1

我在Oracle上運行這兩個查詢之間的區別:SQL查詢分頁:什麼是兩種方法

select B.* from (
    select A.*, rownum as rn from (
     select * from .... order by ... 
    ) A ) B where B.rn > 0 and B.rn <=30; 

select B.* from (
    select A.*, rownum as rn from (
     select * from .... order by ... 
    ) A where rownum <= 30) B where rn > 0 

事實上,這些查詢的結果是不同的。第一個看起來更正確。爲什麼?

問題與第二種方法是: 當我運行它0-30間隔時,它乍看起來確實很好。但是當我以30-60的間隔運行時,我發現30-60的結果確實包含了我在0-30結果中已經看到的輸入(顯然不應該發生)。

UPD: 我剛剛發現,它也許可以正常工作,不是因爲我的order by條款產生不唯一的排序。所以它不會通過PK進行排序,而是通過clientName進行排序,並且結果中可能會有大量相同的客戶端。那麼,它可以是原因嗎?當訂單實際上未定義時,oracle如何輸入條目?如果分頁順序應該定義得非常好,以便在頁面之間切換時結果穩定。

+3

這可能幫助:http://use-the-index-luke.com/sql/partial-results/fetch-next-page –

+0

沒有......他們建議使用完全相同的第二種方法我已經使用過。但它的工作原理錯誤,如上所述 – javagirl

+1

關於您的訂購問題,如果訂單欄不是唯一的,則結果的順序不是確定性的。他們可能會給人以穩定的印象,但這只是因爲查詢執行計劃在當時是穩定的,並且數據沒有改變。你根本無法依靠它。 –

回答

0

您正在引用列別名「rn」,它是從應用之前的內部查詢中分配的rownum派生的。

而是在外部查詢中引用rownum。

select * 
from (
    select * 
    from  ... 
    order by ... 
) 
where rownum between 1 and 30; 

或者......

ROWNUM 0不存在,順便說一句。

select * 
from (
    select a.*, rownum rn 
    from (
    select * 
    from  ... 
    order by ... 
    ) a 
    where rownum < 60 
) 
where rn >= 30 
+0

那麼,爲什麼我的第一個查詢比第二個查詢工作得更好......? – javagirl