【发布时间】:2017-07-27 21:41:14
【问题描述】:
我有一个表格,其中数据如下所示
我的要求是以这样一种方式更新此表,即在一个组内(分组将基于 A 列进行),如果 B 列中有值,则应将相同的值更新到 B 列中的其他行该组中的空值。如果 B 列对该组中的所有记录都有空值,则应生成新序列。我也不能为此使用 pl/SQL 块。我需要编写一个 SQL 查询来执行此操作
我的预期输出如下所示
【问题讨论】:
标签: oracle11g
我有一个表格,其中数据如下所示
我的要求是以这样一种方式更新此表,即在一个组内(分组将基于 A 列进行),如果 B 列中有值,则应将相同的值更新到 B 列中的其他行该组中的空值。如果 B 列对该组中的所有记录都有空值,则应生成新序列。我也不能为此使用 pl/SQL 块。我需要编写一个 SQL 查询来执行此操作
我的预期输出如下所示
【问题讨论】:
标签: oracle11g
您将无法在更新语句中直接使用sequence_name.nextval,因为该值会随着每一行而增加,这意味着您最终会在 b 列中为每个 a 值提供不同的值。
我能想到的最好的方法是首先确保每组全为空的 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 以了解此方法有效的证据。
【讨论】:
类似这样的:
update table t1
set B = (select nvl(max(b),sequence_name.nextval) from table where a=t1.a)
Ps:我无法测试这个。 事实上,我们不能在相关子查询中使用序列...... :( 一种解决方法是使用合并:
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);
有一件事:即使没有插入 nextval,它也总是会被消耗掉。如果你不想这样,你可能需要一些 pl/sql 代码。
【讨论】: