我正在使用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个最大函数。
请帮我解决这个问题。
提前谢谢。
答案 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;
我当然不是说它很漂亮......