Объединение контактов в таблице SQL без создания повторяющихся записей
-
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, который пользователи видят как его атрибут.Это дополнительная работа, но она придаст вам дополнительную последовательность и надежность в долгосрочной перспективе.
Хорошее эмпирическое правило заключается в том, что первичный ключ записи не должен быть доступен пользователям, где это возможно, и делать это следует только после тщательного рассмотрения.Хорошо, я признаюсь, что сам неоднократно нарушал это, но стоит стремиться туда, где это возможно :-)