我有一组数据,其中有多行具有相同的unique_string_identifier
。我想将序列中的新唯一ID分配给具有unique_string_identifier
的行的第一个实例,然后给出具有相同unique_string_identifier
个ID乘以-1的任何后续行。我尝试了三种不同的方式,但我总是得到
ORA-30483:此处不允许使用窗口函数
以下是我的尝试:
UPDATE my_table
set my_id =
CASE WHEN LAG(unique_string_identifier, 1, '-') OVER (order by unique_string_identifier) <> unique_string_identifier THEN my_id_seq.nextval
ELSE LAG(-1 * my_id, 1, '-') OVER (order by unique_string_identifier) END CASE
where import_run_id = a_run_id;
我也试过这个:
UPDATE my_table
set my_id = my_id_seq.nextval
where row_number() over (partition by unique_string_identifier order by line_id) = 1;
//another update statement to make the rows with null ID's equal to the negative id joined on unique_string_identifier
而且:
UPDATE my_Table
set my_id =
decode(unique_string_identifier, LAG(unique_string_identifier, 1, '-') OVER (order by unique_string_identifier), LAG( my_id, 1, '-') OVER (order by unique_string_identifier), my_id_seq.nextval)
where import_run_id = a_run_id;
我该如何做到这一点?
编辑:同样对于我自己的丰富,如果有人能解释为什么这三个陈述(这些对我来说都很不一样)最终会得到完全相同的ORA错误,我会很感激。答案 0 :(得分:2)
我无法找到一个简单的MERGE或一组UPDATE,但这是一个可能正常的解决方案,在Oracle 11g上使用PL / SQL进行测试:
测试场景:
create table my_table (unique_string varchar2(100));
insert into my_table values ('aaa');
insert into my_table values ('aaa');
insert into my_table values ('aaa');
insert into my_table values ('bbb');
insert into my_table values ('bbb');
insert into my_table values ('ccc');
alter table my_table add (id number);
create sequence my_seq;
这是进行更新的PL / SQL:
declare
cursor c is
select unique_string
,row_number()
over (partition by unique_string order by 1)
as rn
from my_table
order by unique_string
for update of id;
r c%rowtype;
begin
open c;
loop
fetch c into r;
exit when c%notfound;
if r.rn = 1 then
update my_table
set id = my_seq.nextval
where current of c;
else
update my_table
set id = my_seq.currval * -1
where current of c;
end if;
end loop;
close c;
end;
/
我的测试结果(请注意,此阶段的序列有所提升):
select * from my_table;
UNIQUE_STRING ID
============= ==
aaa 7
aaa -7
aaa -7
bbb 8
bbb -8
ccc 9
P.S。我有点鬼鬼祟祟,利用Oracle倾向于按行返回的顺序返回ROW_NUMBER;为了更健壮和正确,我将查询放在子查询和ORDER BY unique_string, rn
。