我已经接管了一个项目,该项目在PostgreSQL中有一些现有数据需要调整。具体来说,在团队属于联赛的系统中,我需要从联赛表中删除重复的名称。为此,我需要在teams表中调整外键,以使它们不再引用将要删除的联赛。请注意,我删除哪个联赛和保留哪个联赛都没有关系,只要我为每个不同的联赛名称保留一个联赛即可。
通过示例更容易解释。在下面,我们可以看到“红松鼠”和“绿猴”都属于“西部联盟”联盟,尽管目前有两行名为“西部联盟”。我需要删除Leagues表中的行,以使联盟名称唯一,但是首先我需要更改teams表中的league_ids
,以便他们引用不会删除的League行。
leagues
id | name
1 | "Western League"
2 | "Western League"
3 | "Eastern League"
teams
id | league_id | name
1 | 1 | "Red Squirrels"
2 | 2 | "Green Monkeys"
3 | 3 | "Blue Ducks"
在上面的简单示例中,目标是将“绿猴”上的League_id更改为1,以便“红松鼠”和“绿猴”都引用同一个联赛。此后,没有团队引用第二个“西部联盟”联赛,可以将其删除。我们的数据太多,无法逐行进行更改。
真的很感谢您的帮助。谢谢!
答案 0 :(得分:1)
此查询显示应将哪个联赛替换为另一个联赛:
select id, min(id) over (partition by name) as correct_id
from leagues
id | correct_id
----+------------
3 | 3 -- ok
1 | 1 -- ok
2 | 1 -- needs replacing
(3 rows)
如果我们与团队一起加入,我们可以选择需要更正的团队:
select t.id as team_id, correct_id
from (
select id, min(id) over (partition by name) as correct_id
from leagues
) l
join teams t on t.league_id = l.id
where t.league_id <> correct_id
team_id | correct_id
---------+------------
2 | 1
(1 row)
使用最后一个查询来更新团队:
update teams
set league_id = correct_id
from (
select t.id as team_id, correct_id
from (
select id, min(id) over (partition by name) as correct_id
from leagues
) l
join teams t on t.league_id = l.id
where t.league_id <> correct_id
) c
where id = team_id
returning team_id, name, correct_id
team_id | name | correct_id
---------+-----------------+------------
2 | "Green Monkeys" | 1
(1 row)