使用来自分组的不同表的不同值更新表

时间:2021-01-26 17:24:00

标签: sql oracle

我有一个名为 table1 的 oracle 表,它有一个来自 table2 的外键。 table2 有 2 列:id、name table2.name 有很多重复项需要整理,所以我按名称对 table2 进行分组,每个名称只保留 1 个 id。 但是,table1.table2_id 使用了很多重复的字段。

如何更改所有 table1.table2_id 字段以确保没有重复名称?

目前: 表1:

<头>
id blabla table2_id
1 1001
2 1002
3 1003
4 1004
5 1004
6 1005

表 2:

<头>
id 姓名
1001 鲍勃
1002 鲍勃
1003 鲍勃
1004 杰克
1005 杰克

预期结果: 表1:

<头>
id blabla table2_id
1 1001
2 1001
3 1001
4 1004
5 1004
6 1004

表 2:

<头>
id 姓名
1001 鲍勃
1004 杰克

所以,我需要:

  1. 将所有 table1.table2_id 更新为按名称分组的前 1 个 table2.id
  2. 从 table2 中删除重复的行

由于表 2 中有数以千计的重复字段,因此我无法使用 case..

我正在尝试的解决方案为每个名称返回 1 个 ID,但我在可以更新表的部分失败了。

update table1 d
set d.table2_id  = 
(select
b.id
from table2 b
where b.name in (select min(id) keep(dense_rank first order by id) id
     , name
  from table2
 group by name)
order by b.id ASC
)
where d.table2_id in ( SELECT b.id FROM table2 b WHERE b.name in (select min(id) keep(dense_rank first order by id) id
     , name
  from table2
 group by name));

请帮忙:)

2 个答案:

答案 0 :(得分:1)

这里是语法正确的 Oracle 语句

update table1 t1
set t1.table2_id = (
  select new_id
  from (
    select id, min(id) over (partition by name) new_id
    from table2
  ) d
  where d.id = t1.table2_id
);
delete from table2
where id not in (
  select min(id) from table2 group by name
);

此处使用 analytic function min(id) over (partition by name) 以便您可以将所有原始 ID 与其新 ID(name 相同的集合中的最小 ID)一起使用。< /p>

答案 1 :(得分:0)

这是一种方法:

update table1 d
set d.table2_id = x.id_tokeep
from 
(
select name , id , min(id) over (partition by name ) as id_tokeep
from table2
) x
 where x.id = d.table2_id

delete from table2
where id not in ( select min(id) from table2 group by name)
相关问题