1

我有 53 列和 100 万行左右的表 x。第一列是标识符,接下来的 52 列是从特定日期开始每周发生的货币交易。

例如。

id,w1,w2,w3,w4,w5..w52
a1,0,5,1,4,0..43
a2,7,0,6,9,4..27

我需要每个 id 的所有这些周交易的累积总和。我发现的一种解决方案是使用 unpivot 获取每个 id 的 52 行,然后应用聚合总和。

sum(transaction) over (partition by id order by week asc)

我的问题是我现在有一个包含 6000 万行的表,而 Oracle 通过获取总和进行排序的速度非常慢(令人望而却步)。

另一种选择是我将每一列手动添加在一起,如下所示。

select 
 id,
 w1,
 w1+w2,
 w1+w2+w3,
 w1+w2+w3+w4,
 w1+w2+w3+w4+w5,
 ..
 w1+w2+w3+w4+w5..w49+w50+w51+w52

from x

这里的问题是要获得一个简单的公式需要大量的代码(写出来很痛苦!)。

无论如何我可以调整我的表(索引/分区)以加快这么多行的聚合总和,或者我可以与原始表一起使用的任何代码以最少的努力实现这些结果?!

4

1 回答 1

1

创建一个视图来隐藏“大量代码”。例如:

SQL> desc tester;
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------------
 ID                                                 NUMBER
 W1                                                 NUMBER
 W2                                                 NUMBER
...
 W49                                                NUMBER
 W50                                                NUMBER
 W51                                                NUMBER
 W52                                                NUMBER

然后运行类似的 SQL(在 11g 中,您可以使用listagg而不是达到wm_concat相同的效果):

select 'create or replace view v_tester as select id ' from dual
union all
select * 
  from (select ','||replace(wm_concat(column_name) over (order by column_id), ',', '+') || ' as col' || rownum
  from user_tab_columns
 where table_name = 'TESTER'
   and column_id >= 2
 order by column_id)
union all
select ' from tester;' from dual;

生成 DDL,如:

create or replace view v_tester as select id 
,W1 as col1
,W1+W2 as col2
,W1+W2+W3 as col3
,W1+W2+W3+W4 as col4
,W1+W2+W3+W4+W5 as col5

等等......然后运行它。现在您的代码被视图隐藏了,并且易于生成。

于 2013-03-25T15:30:47.430 回答