2012-11-09 76 views
2

我有一個SQL查詢,看起來像這樣:甲骨文LIMIT和1000列限制

SELECT foo "c0", 
     bar "c1", 
     baz "c2", 
     ... 
FROM some_table 
WHERE ... 

爲了應用的限制,只有從該查詢返回的記錄的子集,我用下面的包裝SQL :

SELECT * 
FROM (
    SELECT t.*, 
      ROW_NUMBER() OVER (ORDER BY ...) rnum 
    FROM (
     ... original SQL goes here ... 
    ) t 
) 
WHERE rnum BETWEEN 1 AND 10 

我的問題是,原來的查詢是選擇超過1000列跨越大量的連接到其他表。 Oracle每個表或視圖的內部限制爲1000列,顯然,我用來限制結果集的包裝器SQL正在創建一個應用此限制的臨時視圖,導致整個事件失敗。

是否有另一種分頁方法不會創建這樣的視圖,或者不會受1000列限制的影響?

我對將工作分解爲塊的建議不感興趣,因爲我已經完全瞭解所有這些方法,所以不要選擇> 1000列等。

+7

「*選擇超過1000列*」,似乎對您的數據模型來說真的很奇怪。 –

+4

@a_horse_with_no_name:如果奇怪,你的意思是我有超過1000件有關單個實體的離散數據,這些數據對於我的特定域來說都是相關且必需的,但是在所有域的集合中這是非常罕見的,重新正確。完全無益,但正確。 – FtDRbwLXw6

+5

在30年的數據庫設計中,我從未見過一個實體需要超過1000列。我不會感到驚訝,如果你的模型可以優化,從而解決問題的根本原因,而不是戰鬥症狀 –

回答

2

你不能有超過1000列的視圖,所以作弊一點。

select * 
    from foo f, foo2 f2 
where (f.rowid, f2.rowid) in (select r, r2 
           from (select r, r2, rownum rn 
             from (select /*+ first_rows */ f.rowid r, f2.rowid r2 
               from foo f, foo2 f2 
               where f.c1 = f2.a1 
                and f.c2 = '1' 
               order by f.c1)) 
           where rn >= AAA 
            and rownum <= BBB) 


order by whatever; 

現在把任何where子句放在最裏面的位(例如,我把f.c1 ='1')。

BBB = pagesize。 AAA =起始點

+0

澄清一下,在這個例子中'f.c1'應該是關鍵字段嗎?並且是'無論什麼順序'應該是我會把結果集應該排序的列?我是這麼認爲的,但是我得到的結果並不是按我放在那裏的順序排列的。我有今天的記錄,並且我指定的第一個'by by'列是修改日期,遞減,但是我看到的結果是從2011年開始訂購的。我認爲這與最內層的訂單有關'。 – FtDRbwLXw6

+0

主要的順序是在內部sql'order by f.c1'中放上你想要的任何東西(外部的那個可能在邏輯上應該是相同的順序) – DazzaL

+0

是f.c1 = f2.a1只是連接鍵你可能有幾個)。我在那裏放兩張桌子,就像你在例子中說的那樣有很多桌子。所以把你想要的所有桌子放在一起..加入他們,然後點他們,但你看到適合..所有內部的SQL。第一行提示是告訴oracle,你只對前幾個結果感興趣(從完全掃描中可以避免它)。 – DazzaL

0

問題分頁還是隻返回前10行?如果是後者,你可以這樣做:

SELECT foo "c0", 
     bar "c1", 
     baz "c2", 
     ... 
FROM some_table 
WHERE ... and 
     rownum <= 10 
+1

這是分頁,所以我需要能夠一次返回一頁結果,從任意偏移量開始,而不是每次只有前10個。 – FtDRbwLXw6

3

好吧,這將執行比你打算什麼更糟糕,但我的觀點是,你可以嘗試分頁這樣:

WITH CTE AS 
(
    ... original SQL goes here ... 
) 

SELECT A.* 
FROM CTE A 
INNER JOIN (SELECT YourKey, 
        ROW_NUMBER() OVER (ORDER BY ...) rnum 
      FROM CTE) B 
ON A.YourKey = B.YourKey 
WHERE rnum BETWEEN 1 AND 10; 
+0

我現在明白了,謝謝你的回答。我試過這種方法,我仍然得到相同的1000列限制錯誤。我認爲這是由於這些查詢使用連接數據作爲子查詢(Oracle試圖創建臨時視圖?),所以列限制正在被應用。 – FtDRbwLXw6

+0

@drrcknlsn我看到了,那麼我需要嘗試用1000列自己的表來查看我是否想出了一些東西 – Lamak

+0

只是爲了說明問題,我的表中沒有任何一個表有1000列以上(它們都少得多)。我只是加入了一堆不同的表格,並且所有表格中所有列的總數都超過了1000. – FtDRbwLXw6