简体   繁体   English

如果父行中的字段值相同,则将连接的表行与相同的父表行关联

[英]Associate joined table rows with same parent table rows if a value of field in parent row is same

I have data in two tables.我有两个表中的数据。 City and Address.城市和地址。

City城市

id - name - code
1  - abc  - 1
2  - xyz  - 2
3  - efg  - 2

Address地址

id - city_id - name
1  -   1     - wer
2  -   2     - sdf
3  -   3     - tyu

Now code for cities with id 2 and 3 are the same.现在 id 为 2 和 3 的城市的代码是相同的。 I want to delete the city with id 3 and change city_id 3 to 2 in the Address table so that the last two rows of Address table are associated with city id 2我想删除 id 为 3 的城市,并将 Address 表中的 city_id 3 更改为 2,以便 Address 表的最后两行与城市 id 2 相关联

In other words, I want to delete duplicate rows in the parent table and update the child table accordingly.换句话说,我想删除父表中的重复行并相应地更新子表。 There are thousands of such rows in my 2 tables.我的 2 个表中有数千行这样的行。

If you are going to do this multiple times then I would suggest you to create a Stored Procedure and call it whenever you need it.如果您打算多次执行此操作,那么我建议您创建一个存储过程并在需要时调用它。

CREATE OR REPLACE PROCEDURE delete_dulicate_city()
LANGUAGE 'plpgsql'
AS $$
BEGIN
    DROP TABLE IF EXISTS temp_city;

    CREATE TEMPORARY TABLE IF NOT EXISTS temp_city
    (
        id_to                      INT,
        id_from                    INT
    );
        
    INSERT INTO temp_city
    SELECT c1.id id_to, c2.id id_from 
    FROM
    (
        SELECT id, code, row_number() over(partition BY code ORDER BY id) rn
        FROM city
    ) c1 
    INNER JOIN city c2 
    ON  c1.rn = 1
    AND c1.code=c2.code 
    AND c2.id > c1.id;

    UPDATE address a
    SET city_id = tc.id_to
    FROM temp_city tc
    WHERE a.city_id=tc.id_from;

    DELETE FROM city 
    WHERE id IN (SELECT id_from FROM temp_city);
END;
$$;

You can call it whenever you need just by executing CALL delete_duplicate_city();您可以在需要时随时调用它,只需执行CALL delete_duplicate_city();

https://onecompiler.com/postgresql/3xzy48uq4 https://onecompiler.com/postgresql/3xzy48uq4

Create a table of pairs to be processed (cc), then update Address and delete from City accordingly创建一个要处理的对表 (cc),然后相应地更新地址并从城市中删除

   select c1.id idto, c2.id idfrom into cc 
   from (
     select id,  code,  row_number() over(partition by code order by id) rn
     from city 
   ) c1 
   join city c2 on c1.rn = 1 and c1.code = c2.code and c2.id > c1.id;

update Address a
set city_id = cc.idto
from  cc
where a.city_id=cc.idfrom;

delete from city 
where id in (select idfrom from cc);

db<>fidle 数据库<>文件夹

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM