Oracle复杂更新语句

时间:2017-07-27 05:48:34

标签: oracle11g

我有一个表格,数据如下所示

enter image description here

我的要求是以这样的方式更新此表:在一个组内(分组将基于A列完成),如果B列中有值,则应将相同的值更新为B列中的其他行该组中的空值。如果列B对该组中的所有记录都具有空值,则应生成新序列。此外,我不能使用pl / SQL块。我需要编写一个SQL查询来执行此操作

我的预期输出低于

enter image description here

2 个答案:

答案 0 :(得分:0)

这样的事情:

merge into teste t1
using (select max(b) as m,a from teste group by a) t2
on (t1.a=t2.a)
when matched then update set b= nvl(t2.m,seq_teste.nextval);

Ps:我无法测试这一点。 实际上我们不能在相关子查询中使用序列...... :( 一种解决方法是使用merge:

{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "baseUrl": ".",
    "paths": {
      "@myproject/*": ["src/app/*"]
    }    
}

有一件事:即使没有插入,也总是会消耗nextval。如果你不想要,你可能需要一些pl / sql代码。

答案 1 :(得分:0)

您将无法在更新语句中直接使用sequence_name.nextval,因为该值会随着每一行而增加,这意味着您的每个值都会在b列中以不同的值结束。

我能想到这样做的最佳方法是首先确保每一组全零b值都有一个值,你可以这样做:

merge into t1 tgt 
  using (select a, 
                b, 
                rid, 
                row_number() over (partition by a order by b) rn 
         from   (select a, 
                        b, 
                        rowid rid, 
                        max(b) over (partition by a) max_b 
                 from   t1) 
         where  max_b is null) src 
    on (tgt.rowid = src.rid and src.rn = 1) 
when matched then 
update set tgt.b = t1_seq.nextval;

这将查找给定a的所有b值为null的行,然后更新其中一个以具有下一个序列值。

完成后,您可以继续根据该组的最大b值填充空值,如下所示:

update t1 
set    b = (select max(b) from t1 t2 where t1.a = t2.a) 
where  b is null;

请参阅this LiveSQL script以获取有效的证据。