2012-11-09 42 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