Найти одну запись, которая существует в виде двух записей в базе данных другого поставщика

#sql-server #database

#sql-server #База данных

Вопрос:

У меня есть две базы данных поставщиков, которые за эти годы ужасно рассинхронизировались, и я пытаюсь это исправить. У одного клиента может быть несколько id_numbers , и эти идентификаторы существуют в обеих базах данных поставщиков. Все идентификаторы для одного клиента правильно привязаны к одной записи клиента в Vendor1 базе данных (что означает, что они принадлежат одному и тому же customer_code ). Проблема, однако, заключается в том, что одни и те же идентификаторы могут быть разделены между несколькими клиентами в Vendor2 базе данных, что неверно. Мне нужно будет объединить эти несколько клиентов вместе в Vendor2 базе данных.

Я пытаюсь определить, какие клиенты представлены как два или более клиентов во второй базе данных поставщика. До сих пор я объединил их вместе, но я не могу понять, как найти только клиентов, у которых есть два или более разных MemberInternalKeys для одного и того же customer_code .

Вот что у меня есть на данный момент:

 select top 10
    c.customer_code,
    i.id_number,
    cc.MemberInternalKey
from Vendor1.dbo.customer_info as c
join Vendor1.dbo.customer_ids as i
  on c.customer_code = i.customer_code
join Vendor2.dbo.Clubcard as cc
  on (i.id_number collate Latin1_General_CI_AS_KS) = cc.ClubCardId
where i.id_code = 'PS'
  

В приведенном ниже примере я ожидал бы получить обратно только последние две строки в таблице. Первые две строки не должны включаться в результаты, поскольку они одинаковы MemberInternalKey для обеих записей и принадлежат одному и тому же customer_code . Третья строка также не должна включаться, поскольку между обеими базами данных поставщиков имеется совпадение 1-1.

 customer_code | id_number | MemberInternalKey
--------------|-----------|------------------
5549032       | 4000      | 4926877
5549032       | 4001      | 4926877
5031101       | 4007      | 2379218
2831779       | 4029      | 1763760
2831779       | 4062      | 4950922
  

Любая помощь приветствуется.

Ответ №1:

Если я правильно понимаю, вы можете использовать оконные функции для этой логики:

 select c.*
from (select c.customer_code, i.id_number, cc.MemberInternalKey,
             min(MemberInternalKey) over (partition by customer_code) as minmik,
             max(MemberInternalKey) over (partition by customer_code) as maxmik
      from Vendor1.dbo.customer_info c join
           Vendor1.dbo.customer_ids i
           on c.customer_code = i.customer_code join
           Vendor2.dbo.Clubcard as cc
           on (i.id_number collate Latin1_General_CI_AS_KS) = cc.ClubCardId
      where i.id_code = 'PS'
     ) c
where minmik <> maxmik;
  

Это вычисляет минимум и максимум MemberInternalKey для каждого customer_code . Затем outer where возвращает только те строки, в которых они отличаются.

Ответ №2:

Другой вариант

 Declare @YourTable table (customer_code int, id_number int, MemberInternalKey int)
Insert Into @YourTable values
(5549032,4000,4926877),
(5549032,4001,4926877),
(5031101,4007,2379218),
(2831779,4029,1763760),
(2831779,4062,4950922)

Select A.*
 From  @YourTable A
 Join (
        Select customer_code
         From  @YourTable
         Group By customer_code
         Having min(MemberInternalKey)<>max(MemberInternalKey)
      ) B on A.customer_code=B.customer_code
  

ВОЗВРАТ

 customer_code   id_number   MemberInternalKey
2831779         4029        1763760
2831779         4062        4950922