合并SQL表中的联系人而不创建重复的条目

问题描述 投票:1回答:4

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

理想情况下,我想称之为简单的东西

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

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

编辑:使用多个ListID。如果将SourcePerson分配给ListIDs 1,2和3,并将DestinationPerson分配给ListID 3和4,则最终结果需要有四行 - DestinationPerson分配给ListID 1,2,3和4。

sql tsql duplicate-data
4个回答
3
投票
--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

0
投票

首先,您应该将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

0
投票

我必须在这里同意David B.删除所有不应该存在的旧东西,然后进行更新。


0
投票

实际上,我认为你应该回过头来重新考虑你的数据库设计,因为你真的不应该在你正在建议的情况下更改记录的主键 - 这意味着PersonID列实际上并不存在首先是一个合适的主键。

我的猜测是你的PersonID暴露给你的用户,他们因为某些原因重新编号了他们的数据库,你正在将改变同步回来。这通常是一个糟糕的主意,因为它打破了审计跟踪和时间一致性。在这些情况下,通常最好使用您自己的不变主键 - 通常是标识 - 并设置用户看到的PersonID作为其属性。这是额外的工作,但从长远来看,它将为您提供额外的一致性和稳健性。

一个好的经验法则是记录的主键不应该在可能的情况下暴露给用户,并且只有在仔细考虑之后才能这样做。好吧,我承认在很多场合打破了这一点,但值得努力争取到哪里:-)

© www.soinside.com 2019 - 2024. All rights reserved.