Объединение контактов в таблице SQL без создания повторяющихся записей

StackOverflow https://stackoverflow.com/questions/135173

  •  02-07-2019
  •  | 
  •  

Вопрос

У меня есть таблица, содержащая только два столбца — 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.

Это было полезно?

Решение

--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

Другие советы

Сначала вам следует подписаться на 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

Здесь я должен согласиться с Дэвидом Б.Удалите все старые вещи, которых там не должно быть, а затем выполните обновление.

На самом деле, я думаю, вам следует вернуться и пересмотреть структуру своей базы данных, поскольку вам действительно не следует поступать в обстоятельствах, когда вы меняете первичный ключ для записи, как вы предлагаете сделать - это означает, что столбец PersonID на самом деле не в первую очередь подходящий первичный ключ.

Я предполагаю, что ваш PersonID доступен вашим пользователям, они по какой-то причине изменили нумерацию своей базы данных, и вы снова синхронизируете это изменение.Как правило, это плохая идея, поскольку она нарушает контрольные журналы и временную согласованность.В таких обстоятельствах, как правило, лучше использовать собственный неизменяемый первичный ключ (обычно идентификатор) и настроить PersonID, который пользователи видят как его атрибут.Это дополнительная работа, но она придаст вам дополнительную последовательность и надежность в долгосрочной перспективе.

Хорошее эмпирическое правило заключается в том, что первичный ключ записи не должен быть доступен пользователям, где это возможно, и делать это следует только после тщательного рассмотрения.Хорошо, я признаюсь, что сам неоднократно нарушал это, но стоит стремиться туда, где это возможно :-)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top