我有一个名为 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 | 杰克 |
所以,我需要:
由于表 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));
请帮忙:)
答案 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)