如何使用重复 ID 更新引用 table?

How to update reference table with duplicate id?

我正在使用 postgresql。 要删除 table 中的重复项,我使用此查询:

DELETE FROM dups a USING (
      SELECT MIN(ctid) as ctid, key
        FROM dups 
        GROUP BY key HAVING COUNT(*) > 1
      ) b
      WHERE a.key = b.key 
      AND a.ctid <> b.ctid

参考:

但是,还有一个 table 说 ref_table,其中也引用了 dups.id。在删除重复项之前,我需要更新另一个 table。 用重复的 ID 更新引用 table 的查询是什么,这样就不会丢失数据?

例如:

Table 1、说dups

id key
1  Luna
2  Hermione
3  Luna

Table 2、说ref_table

id dups_id data
1   2     Auror
2   1     Researcher

现在删除重复项的查询将删除 dups table 中 ID 为 1 的记录,因为它是重复项。 但是 ref_table 中引用了该记录,因此我需要使用将要保留的记录更新它。

即)Table1 应该变成:

id key
2  Hermione
3  Luna

和Table 2 应该变成:

id dups_id data
1   2     Auror
2   3     Researcher

您可以使用 CTE:

with d as (
      DELETE FROM dups a USING
             (SELECT MIN(ctid) as ctid, key
              FROM dups 
              GROUP BY key HAVING COUNT(*) > 1
             ) b
      WHERE a.key = b.key AND a.ctid <> b.ctid
      RETURNING *
     )
update othertable
   set . . .
   from d
   where . . .;

使用 CTE 来识别 dups 中维护的行,然后更新 ref 行,使 FK 仅指向它们,最后删除不再需要的行。

with keeper as                                     -- identify dups rows to be kept
     ( select id, key
            , max(id) over(partition by key) mid 
         from dups)

   , u as                                          -- update ref so dup_id references only those being kept
     ( update ref r 
        set dup_id =  (select k.mid 
                         from keeper k
                         join dups   d 
                           on (k.id=d.id)
                        where r.dup_id != k.mid
                          and r.dup_id = k.id
                      )
     )   

delete                                             -- final target remove dups rows no lnger needed
  from dups d                                            
 where d.id not in (select mid from keeper);