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

时间:2018-05-30 19:42:14

标签: postgresql

我有两个表:一个包含不同的人,另一个表包含地名。每个人都与地名ID相关联 - 地名ID提供了有关地点的更多信息(例如姓名,经度和纬度)。 地名表是倾斜的,有很多半重复(名称写得有点不同,例如伦敦/伦敦)。对于每个地名,我现在也拥有真实的'地名通过Google 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

现在我想知道是否可以更新人员表,因此简和汤姆都获得相同的出生地ID(如果它是3或4则无关紧要)然后从地名表中删除重复的行,以便ID为3的地名或ID为4的地名仍然存在,具体取决于哪一个留在人员表中。

如果我完全朝着错误的方向前进,通过尝试用SQL来解决这个问题,我也想知道。我使用Java和Spring访问数据库。

1 个答案:

答案 0 :(得分:0)

因为,使用哪个id替换无关紧要,让我们在重复列表中获取第一个id。

即。

birthplace
3
4

变为

birthplace
3
3

首先创建一个表格映射原始&替换id值

你的select语句有原始ID,你可以使用first_value

分区的窗口函数googleplacename添加替换ID

update persons语句的from子句中使用此映射表,加入birthplace等于original_id但不是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