Поиск дубликатов между двумя таблицами - PullRequest
1 голос
/ 28 февраля 2011

У меня есть две таблицы SQL2008, одна из которых представляет собой таблицу «Import», содержащую новые данные, а другая - таблицу «Destination» с действительными данными.Обе таблицы похожи, но не идентичны (в таблице Destination больше столбцов, обновленных системой CRM), но в обеих таблицах есть три поля «телефонный номер» - Tel1, Tel2 и Tel3.Мне нужно удалить все записи из таблицы импорта, где любые телефонных номеров уже существуют в таблице назначения.

Я попытался собрать простой запрос (просто выбрать SELECT для проверкитолько сейчас):

select t2.account_id
from ImportData t2,  Destination t1 
where 
(t2.Tel1!='' AND (t2.Tel1 IN (t1.Tel1,t1.Tel2,t1.Tel3)))
or
(t2.Tel2!='' AND (t2.Tel2 IN (t1.Tel1,t1.Tel2,t1.Tel3)))
or
(t2.Tel3!='' AND (t2.Tel3 IN (t1.Tel1,t1.Tel2,t1.Tel3)))

... но я знаю, что это почти наверняка не способ делать вещи, тем более, что это очень медленно.Кто-нибудь может указать мне правильное направление?

Ответы [ 3 ]

3 голосов
/ 28 февраля 2011

этот запрос требует немного больше, чем эта информация.Если вы хотите написать это эффективным способом, нам нужно знать, есть ли больше дубликатов при каждой загрузке или больше новых записей.Я предполагаю, что account_id является первичным ключом и имеет кластеризованный индекс.

Я бы использовал подход временной таблицы, который создает нормализованную таблицу #r с индексом phone_no и account_id, например

SELECT Phone, Account into #tmp
FROM 
   (SELECT account_id, tel1, tel2, tel3
   FROM destination) p
UNPIVOT
   (Phone FOR Account IN 
      (Tel1, tel2, tel3)
)AS unpvt;

создать некластеризованный индекс для этой таблицы с первым столбцом номера телефона, а второй - номером счета.Вы не можете избежать одного полного сканирования таблицы, поэтому я предполагаю, что вы можете сканировать импорт (возможно, меньше).затем просто присоединитесь к этой таблице и используйте описатель несуществования, как описано.Затем, конечно, бросить стол после обработки * Luke

1 голос
/ 28 февраля 2011

Я не уверен в производительности этого запроса, но, поскольку я приложил усилия, чтобы написать его, я все равно опубликую его ...

;with aaa(tel)
as
(
select Tel1
from Destination
union
select Tel2
from Destination
union
select Tel3
from Destination
)
,bbb(tel, id)
as
(
select Tel1, account_id
from ImportData
union
select Tel2, account_id
from ImportData
union
select Tel3, account_id
from ImportData
)

select distinct b.id
from bbb b
where b.tel in
(
select a.tel
from aaa a
intersect
select b2.tel
from bbb b2
)
1 голос
/ 28 февраля 2011

Exists закоротит запрос и не выполнит полный обход таблицы, как соединение. Вы также можете изменить рефракцию условия where, если это все еще не работает так, как вы хотите.

SELECT *
FROM ImportData t2
WHERE NOT EXISTS (
    select 1 
    from Destination t1
    where (t2.Tel1!='' AND (t2.Tel1 IN (t1.Tel1,t1.Tel2,t1.Tel3)))
          or
          (t2.Tel2!='' AND (t2.Tel2 IN (t1.Tel1,t1.Tel2,t1.Tel3)))
          or
          (t2.Tel3!='' AND (t2.Tel3 IN (t1.Tel1,t1.Tel2,t1.Tel3)))
    )
...