Вот как я это сделал, с небольшим поднятым вверх руками в воздухе.
Шаг первый, определите наборы предметов для сравнения.Это:
- Для «первичного» значения все значения, найденные в псевдониме
- Включая также «первичное» значение (для охвата этого случая наса / ностромо)
Набор в таблице (A или B) идентифицируется по его первичному значению.Что действительно усложняет, так это то, что основное значение не распределяется между двумя таблицами (sally @ mars, sally @ nasa).Таким образом, мы можем сравнивать наборы, но мы должны иметь возможность «вернуться» к основному на каждой таблице отдельно (например, выделение из таблицы B может быть sally @ nasa / ripley @ nostroomo, но мы должны добавить sally @mars / ripley @ nostromo к таблице A)
Основные проблемы возникают, если в таблице первичное значение отображается как псевдоним другого первичного значения (например, в таблице A chris @ work отображается как псевдоним длябоб @ тест).Ради здравомыслия я собираюсь предположить, что этого не произойдет ... но если это произойдет, проблема станет еще сложнее.
Этот запрос работает для добавления недостающих элементов в B, которые не находятся в A, гдеPrimaryAddress одинаков для A и B:
;WITH setA (SetId, FullSet)
as (-- Complete sets in A
select PrimaryAddress, AliasAdress
from A
union select PrimaryAddress, PrimaryAddress
from A
)
,setB (SetId, FullSet)
as (-- Complete sets in B
select PrimaryAddress, AliasAdress
from B
union select PrimaryAddress, PrimaryAddress
from B
)
,NotInB (Missing)
as (-- What's in A that's not in B
select FullSet
from setA
except select FullSet -- This is the secret sauce. Definitely worth your time to read up on how EXCEPT works.
from setB
)
-- Take the missing values plus their primaries from A and load them into B
INSERT B (PrimaryAddress, AliasAdress)
select A.PrimaryAddress, nB.Missing
from NotInB nB
inner join A
on A.AliasAdress = nb.Missing
Запустите его снова с перевернутыми таблицами (начиная с «NotInB»), чтобы сделать то же самое для A.
HOWEVER
Выполнение этого с вашими образцами данных для "in B, а не A" добавит (sally @ nasa, ripley @ nostromo) к A, и, поскольку это другой первичный объект, будет создан новыйставить и так не решает проблему.Это становится ужасно быстро.Говорите это отсюда:
- Делает два прохода, один для A не в B, один для B не в A
- Для каждого прохода необходимо сделать две проверки
- Первая проверка - это то, что указано выше: что находится в A, а не в B, где совпадают первичные адреса, и добавьте его
- Вторая проверка выглядит ужасно: что находится в A, а не в B, где первичные адреса из A НЕ являются первичнымиадрес в B и, таким образом, должен быть псевдонимом.Здесь найдите первичный адрес A в списке псевдонимов B, получите первичный ключ, используемый для этого набора в B, и создайте строки в B, используя эти значения.