Postgresql:给定来自另一个表的ID数组,更新一个表中的多行

Postgresql:给定来自另一个表的ID数组,更新一个表中的多行,postgresql,Postgresql,我有两个表:一个包含不同的人,另一个包含地名。每个人都会连接到一个地名ID,而地名ID会提供有关该地点的更多信息(例如名称、经度和纬度)。 地名表是倾斜的,有很多半重复(名称写得有点不同,例如伦敦/伦敦)。对于每个地名,我现在也通过谷歌API获得了“真实”的地名 人员: ID Name Birthplace 1 John 1 2 Sarah 2 3 Jane 3 4 Tom 4 地名: ID PlaceName

我有两个表:一个包含不同的人,另一个包含地名。每个人都会连接到一个地名ID,而地名ID会提供有关该地点的更多信息(例如名称、经度和纬度)。 地名表是倾斜的,有很多半重复(名称写得有点不同,例如伦敦/伦敦)。对于每个地名,我现在也通过谷歌API获得了“真实”的地名

人员:

ID    Name     Birthplace
1     John     1
2     Sarah    2
3     Jane     3
4     Tom      4
地名:

ID   PlaceName       GooglePlaceName
1    New York City   New York, NY, USA    
2    Amsterdam       Amsterdam, Netherlands
3    Londen          London, UK
4    London          London, UK
所以当看这些数据时,简和汤姆实际上来自同一个地方

我已经有一个从地名表中获取重复ID的查询:

SELECT id FROM placenames WHERE googleplacename IN (SELECT googleplacename FROM placenames GROUP BY googleplacename HAVING COUNT (googleplacename) > 1);
这是回报

    ID
1   3
2   4
现在我想知道是否可以更新person表,因此Jane和Tom都获得相同的出生地ID(不管是3还是4),然后从place name表中删除重复的行,以便保留ID为3的地名或ID为4的地名,具体取决于保留在persons表中的是哪一行


如果我完全走错了方向,通过尝试用SQL解决这个问题,我也想知道。我正在使用Java和Spring来访问数据库。

因为使用哪个id来替换并不重要,让我们在重复列表中取第一个id

i、 e

变成

birthplace
3
3
为此,首先创建一个映射原始id值和替换id值的表

select语句具有原始ID,您可以使用窗口函数
first\u value
通过
googleplacename
分区添加替换ID

updatepersons
语句的from子句中使用此映射表,在
出生地
等于
原始id
但不等于
替换id
的记录中加入此映射表

UPDATE persons
SET birthplace = replacement_id

FROM (
  SELECT id original_id, FIRST_VALUE(id) OVER (PARTITION BY googleplacename) replacement_id
  FROM placenames 
  WHERE googleplacename IN (
    SELECT googleplacename FROM placenames GROUP BY 1 HAVING COUNT(*) > 1
  ) 
) replacement_table
WHERE birthplace = original_id
  AND birthplace != replacement_id
UPDATE persons
SET birthplace = replacement_id

FROM (
  SELECT id original_id, FIRST_VALUE(id) OVER (PARTITION BY googleplacename) replacement_id
  FROM placenames 
  WHERE googleplacename IN (
    SELECT googleplacename FROM placenames GROUP BY 1 HAVING COUNT(*) > 1
  ) 
) replacement_table
WHERE birthplace = original_id
  AND birthplace != replacement_id