【问题标题】:Merging contacts in SQL table without creating duplicate entries合并 SQL 表中的联系人而不创建重复条目
【发布时间】:2010-09-13 04:56:30
【问题描述】:

我有一个只包含两列的表 - ListID 和 PersonID。当一个人在系统中与另一个人合并时,我要将来自“源”人的所有引用更新为对“目标”人的引用。

理想情况下,我想调用一些简单的东西,例如

UPDATE MailingListSubscription
SET PersonID = @DestPerson
WHERE PersonID = @SourcePerson

但是,如果目标人员已经存在于此表中,并且与源人员具有相同的 ListID,则会创建重复条目。如何在不创建重复条目的情况下执行此操作? (ListID,PersonID为主键)

编辑:使用了多个 ListID。如果 SourcePerson 分配给 ListID 1、2 和 3,DestinationPerson 分配给 ListID 3 和 4,那么最终结果需要有四行 - DestinationPerson 分配给 ListID 1、2、3 和 4。

【问题讨论】:

    标签: sql tsql duplicate-data


    【解决方案1】:
    --out with the bad
    DELETE
    FROM MailingListSubscription
    WHERE PersonId = @SourcePerson
      and ListID in (SELECT ListID FROM MailingListSubscription WHERE PersonID = @DestPerson)
    
    --update the rest (good)
    UPDATE MailingListSubscription
    SET PersonId = @DestPerson
    WHERE PersonId = @SourcePerson
    

    【讨论】:

    • 两者都写在查询分析器中。看了执行计划。显示相同的计划。 “存在”与“存在”无关紧要。 PersonId 的索引非常重要。
    【解决方案2】:

    首先,您应该将 destperson 订阅到 SourcePerson 订阅但 Destperson 尚未订阅的所有列表。然后删除所有 SourcePersons 订阅。 这将适用于多个 ListID。

    Insert into MailingListSubscription
    (
       ListID,
       PersonID
    )
    Select
       ListID,
       @DestPerson
    From
       MailingListSubscription as t1
    Where
       PersonID = @SourcePerson and
       Not Exists
       (
          Select *
          From MailingListSubscription as t2
          Where
             PersonID = @DestPerson and
             t1.ListID = t2.ListID
       )
    
    
    
    Delete From MailingListSubscription
    Where
       PersonID = @SourcePerson
    

    【讨论】:

      【解决方案3】:

      我必须同意 David B 的观点。删除所有不应该存在的旧内容,然后进行更新。

      【讨论】:

        【解决方案4】:

        实际上,我认为您应该返回并重新考虑您的数据库设计,因为您确实不应该按照您的提议更改记录的主键 - 这意味着 PersonID 列首先实际上不是一个合适的主键。

        我的猜测是您的 PersonID 向您的用户公开,他们出于某种原因重新编号了他们的数据库,而您正在同步更改。这通常是一个糟糕的主意,因为它破坏了审计跟踪和时间一致性。在这些情况下,通常最好使用您自己的不变主键(通常是身份)并将用户视为其属性的 PersonID 设置。这是一项额外的工作,但从长远来看会给您带来额外的一致性和稳健性。

        一个好的经验法则是尽可能不向用户公开记录的主键,并且您应该在仔细考虑后才这样做。好吧,我承认我自己在很多场合都打破了这一点,但值得在你能做到的地方努力:-)

        【讨论】:

        • 我认为情况并非如此。可能就像数据录入员在系统中没有找到 Bill Smith 一样简单(就像 William Smith 一样),所以创建了一个新条目。后来发现错误,所以合并了比尔和威廉史密斯。在这两种情况下,数据库都会自动生成 ID。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多