首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从表中删除重复项,并将引用行重新链接到新的母版

从表中删除重复项,并将引用行重新链接到新的母版
EN

Stack Overflow用户
提问于 2018-11-19 06:17:06
回答 2查看 418关注 0票数 1

我有一个表transcription,其中包含转录文本的段落和它们的引文:

text, transcription_id(PK), t_notes, citation

第二个表town_transcription是将文本中引用的位置(来自另一个表)链接到该转录记录的关系表。此表包含以下各列:

town_id(FK), transcription_id(FK), confidence_interval

这些文本中的许多段落都引用了多个城镇,但愚蠢的是,我只是复制了记录,并将它们分别链接到每个城镇。我已经使用以下SQL查询识别了重复的文本行:

代码语言:javascript
复制
SELECT * FROM transcription aa
WHERE (select count(*) from transcription bb
WHERE (bb.text = aa.text) AND (bb.citation = aa.citation)) > 1
ORDER BY text ASC;

我现在有大约2000行(一些文本段落的2到6个副本),我需要从transcription表中删除多余的transcription_id,并将关系表中的transcription_id更改为指向剩余的、现在唯一的转录记录。从阅读其他问题来看,我认为利用UPDATE FROMINNER JOIN可能是必要的,但我真的不知道如何实现这一点,我只是一个初学者,谢谢你的帮助。

EN

回答 2

Stack Overflow用户

发布于 2018-11-19 08:23:55

这一条命令应该可以完成所有的工作:

代码语言:javascript
复制
WITH blacklist AS (  -- identify duplicate IDs and their master
   SELECT *
   FROM  (
      SELECT transcription_id
           , min(transcription_id) OVER (PARTITION BY text, citation) AS master_id
      FROM   transcription
      ) sub
   WHERE  transcription_id <> master_id
   )
, upd AS (  -- redirect referencing rows
   UPDATE town_transcription tt
   SET    transcription_id = b.master_id
   FROM   blacklist b
   WHERE  b.transcription_id = tt.transcription_id
   )
DELETE FROM transcription t  -- kill dupes (now without reference)
USING  blacklist b
WHERE  b.transcription_id = t.transcription_id;

由于缺乏定义,我选择每个组ID最小的行作为幸存的主行。

除非您具有非默认设置,否则FK约束不会妨碍您。详细说明:

删除重复项后,您现在可能需要添加一个UNIQUE约束,以防止再次发生相同的错误:

代码语言:javascript
复制
ALTER TABLE transcription
ADD CONSTRAINT transcription_uni UNIQUE (text, citation);
票数 1
EN

Stack Overflow用户

发布于 2018-11-19 08:23:44

使用row_number() over(...)标识重复信息的行。over子句中的partition by text, citation将强制这些值的每个唯一集合的行号序列从1重新开始:

代码语言:javascript
复制
select
     *
from (
       select
              text, transcription_id, t_notes, citation
            , row_number() over(partition by text, citation 
                                order by transcription_id) as rn
       from transcription 
     ) d
where rn > 1

一旦将这些行验证为不需要的行,就可以对delete语句使用相同的逻辑。

但是,您可能会 t_notes列中包含的松散信息-您愿意这样做吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53366008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档