Sql 用最后一个非空值填充空值=>;大量的列
我想将行从源_表复制到目标_表,同时用最后一个非空值填充空值 我所拥有的:Sql 用最后一个非空值填充空值=>;大量的列,sql,oracle,lag,Sql,Oracle,Lag,我想将行从源_表复制到目标_表,同时用最后一个非空值填充空值 我所拥有的: SOURCE_TABLE : A | B | C | PARENT | SEQ_NUMBER 1 | 2 | NULL | 1 | 1 NULL | NULL | 1 | 1 | 2 NULL | 3 | 2 | 1 | 3 DEST_TABLE is em
SOURCE_TABLE :
A | B | C | PARENT | SEQ_NUMBER
1 | 2 | NULL | 1 | 1
NULL | NULL | 1 | 1 | 2
NULL | 3 | 2 | 1 | 3
DEST_TABLE is empty
我想要的是:
DEST_TABLE :
A | B | C | PARENT | SEQ_NUMBER
1 | 2 | NULL | 1 | 1
1 | 2 | 1 | 1 | 2
1 | 3 | 2 | 1 | 3
为了实现这一点,我将动态生成以下SQL:
insert into TARGET_TABLE (A, B, C)
select coalesce(A, lag(A ignore nulls) over (partition by parent order by seq_number)) as A,
coalesce(B, lag(B ignore nulls) over (partition by parent order by seq_number)) as B,
coalesce(C, lag(C ignore nulls) over (partition by parent order by seq_number)) as C,
from SOURCE_TABLE;
如果源表和目标表有少量列,那么一切都可以正常工作。在我的例子中,它们有400多个列(是的,这很糟糕,但它是遗留的,无法更改),我得到了以下错误:
ORA-01467:排序键太长
- 首先,我真的不理解这个错误。这是因为我使用了太多的滞后函数,它们自己使用“orderby”/“partitionby”?将合并(A,滞后(A…)替换为合并(A,A),错误消失
- 那么,是否有一种变通方法或其他方法来实现相同的结果
Thx只需使用pl/sql匿名块即可:
declare
x tgt_table%rowtype; --keep values from last row
begin
for r in (select * from src_table order by seq_number) loop
x.a := nvl(r.a, x.a);
...
x.z := nvl(r.z, x.z);
insert into tgt_table
values x;
end loop;
end;
可能的解决方法:创建两个或多个目标表,每个表都有序号和剩余列的子集,按照您所了解的方式填充它们,最后将它们连接起来。您是否可以复制内容并在之后执行更新以替换
NULL
值?ammoQ:插入前50列,然后插入下50列。。。这确实很有效。我只关心表演。另外,我不知道如何计算不会导致“排序键太长”错误的最大列数。我觉得这取决于栏目的内容,而不仅仅是栏目的数量!在我的一个例子中,它可以工作到213列??!!Peter:我已经尝试过这个解决方案,但出现了相同的错误:(就性能而言,这样可以吗?我的表也是一个参数,这意味着代码必须能够动态处理不同的表。@Olivier您可以动态生成pl/sql块(基于表定义)并使用execute immediate执行。您可以使用forall进一步提高性能。尝试了此解决方案,效果非常好。我真的认为进行大规模查询比逐行处理快得多。但在这种情况下,情况正好相反。谢谢。