在oracle sql 9i中排序键太长错误

时间:2014-02-14 07:06:29

标签: sql oracle function max oracle9i


我正在使用Oracle 9i SQL数据库。我想写一个像这样的查询

select
id_process_inst,<br>
max(case when id_data=34756 then value_text end),<br>
max(case when id_data=34760 then value_text end),<br>
max(case when id_data=34793 then value_text end),<br>
max(case when id_data=34792 then value_text end),<br>
max(case when id_data=34790 then value_text end),<br>
max(case when id_data=34761 then value_text end),<br>
max(case when id_data=34791 then value_text end),<br>
max(case when id_data=34766 then value_text end),<br>
max(case when id_data=34778 then value_text end),<br>
max(case when id_data=34767 then value_text end),<br>
m....<br>
from<br>
(<br>
select <br>
procreldata.id_inst,<br>
dataset.value_text,<br>
procreldata.id_data<br>
from wfdata procreldata<br>
inner join wfvalue dataset<br>
on dataset.id_data= procreldata.id_data<br>
where procreldata.id_inst=177262<br>
)<br>
group by id_inst;<br>

每当我尝试执行此查询时,我都会收到“Sort key too long”错误。我想这是因为我在此查询中使用了大约32个最大函数。
请帮我解决这个问题。
提前谢谢。

1 个答案:

答案 0 :(得分:1)

Ask Tom article I linked to表明这是数据值以及列数的问题,这似乎就是那里显示的例子的情况;但在这种情况下,它显然只是列数。

这是一个真正的黑客,但似乎工作。这里t42有效地表示真实表之间的连接结果。如果我创建该虚拟表并添加几行数据最少:

create table t42 (inst_id number, id_data number, value_text varchar2(4000));

insert into t42 values (1, 1, 'w');
insert into t42 values (1, 2, 'x');
insert into t42 values (1, 3, 'y');
insert into t42 values (1, 4, 'z');

然后这仍然失败:

select max(case when id_data = 1 then value_text end),
  max(case when id_data = 2 then value_text end),
  max(case when id_data = 3 then value_text end),
  max(case when id_data = 4 then value_text end),
  max(case when id_data = 5 then value_text end),
  max(case when id_data = 6 then value_text end),
  max(case when id_data = 7 then value_text end),
  max(case when id_data = 8 then value_text end),
  max(case when id_data = 9 then value_text end),
  max(case when id_data = 10 then value_text end),
  max(case when id_data = 11 then value_text end),
  max(case when id_data = 12 then value_text end),
  max(case when id_data = 13 then value_text end),
  max(case when id_data = 14 then value_text end),
  max(case when id_data = 15 then value_text end),
  max(case when id_data = 16 then value_text end)
from t42
group by inst_id;

from t42
     *
ERROR at line 17:
ORA-01467: sort key too long

我只需要16个聚合表达式,我猜这仍然与我的块大小有关,在我仍然存在的唯一9i数据库中是2k。如果您需要32列来获取错误,那么我猜您的块大小是4k。除非你能增加它,否则不确定真的很重要。

经过一些实验,这是我发现的第一个替代方案:

with t as (
  select inst_id, id_data,
    case when id_data = 1 then value_text end as x1,
    case when id_data = 2 then value_text end as x2,
    case when id_data = 3 then value_text end as x3,
    case when id_data = 4 then value_text end as x4,
    case when id_data = 5 then value_text end as x5,
    case when id_data = 6 then value_text end as x6,
    case when id_data = 7 then value_text end as x7,
    case when id_data = 8 then value_text end as x8,
    case when id_data = 9 then value_text end as x9,
    case when id_data = 10 then value_text end as x10,
    case when id_data = 11 then value_text end as x11,
    case when id_data = 12 then value_text end as x12,
    case when id_data = 13 then value_text end as x13,
    case when id_data = 14 then value_text end as x14,
    case when id_data = 15 then value_text end as x15,
    case when id_data = 16 then value_text end as x16
  from t42
)
select (select max(x1) from t t2 where t2.inst_id = t.inst_id),
  (select max(x2) from t t2 where t2.inst_id = t.inst_id),
  (select max(x3) from t t2 where t2.inst_id = t.inst_id),
  (select max(x4) from t t2 where t2.inst_id = t.inst_id),
  (select max(x5) from t t2 where t2.inst_id = t.inst_id),
  (select max(x6) from t t2 where t2.inst_id = t.inst_id),
  (select max(x7) from t t2 where t2.inst_id = t.inst_id),
  (select max(x8) from t t2 where t2.inst_id = t.inst_id),
  (select max(x9) from t t2 where t2.inst_id = t.inst_id),
  (select max(x10) from t t2 where t2.inst_id = t.inst_id),
  (select max(x11) from t t2 where t2.inst_id = t.inst_id),
  (select max(x12) from t t2 where t2.inst_id = t.inst_id),
  (select max(x13) from t t2 where t2.inst_id = t.inst_id),
  (select max(x14) from t t2 where t2.inst_id = t.inst_id),
  (select max(x15) from t t2 where t2.inst_id = t.inst_id),
  (select max(x16) from t t2 where t2.inst_id = t.inst_id)
from t
group by inst_id;

(SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL (SEL
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
w    x    y    z

所有的自连接都很痛苦,但至少它们是在你的主查询的结果集中,所以你仍然只能击中你的真实表一次 - 其余只需要足够的内存来管理所有的数据带回来。

由于现在主查询中没有发生聚合,只有在子查询中,使用distinct而不是group by可能更清楚,但效果是相同的:< / p>

...
select distinct inst_id,
  (select max(x1) from t t2 where t2.inst_id = t.inst_id),
  ...
  (select max(x16) from t t2 where t2.inst_id = t.inst_id)
from t;

这只是一个示范。如果我使用t42作为假冒数据的占位符,请将原始查询重新放入,并根据需要添加任意数量的聚合;所以在with条款中:

with t as (
   select inst_id, id_data,
    case when id_data = 34756 then value_text end as x1,
    ...
    case when id_data = 34999 then value_text end as x32
  from (
    select procreldata.id_inst,
    dataset.value_text,
    procreldata.id_data
    from wfdata procreldata
    inner join wfvalue dataset
    on dataset.id_data= procreldata.id_data
    where procreldata.id_inst=177262
  )
)
select distinct inst_id,
  (select max(x1) from t t2 where t2.inst_id = t.inst_id),
  ...
  (select max(x32) from t t2 where t2.inst_id = t.inst_id)
from t;

我当然不是说它很漂亮......