2011-02-28 87 views
1

我有两个SQL2008表,一个是包含新数据的“导入”表,另一个是包含实时数据的“目标”表。两个表类似但不相同(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))) 

...但我知道这是几乎可以肯定不是这样做的事情,特别是因为它非常缓慢。任何人都可以将我指向正确的方向吗?

回答

1

我不知道这个查询的perforamance,但因为我做了写它的努力,我无论如何都会发布之后...

;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 
) 
+0

谢谢 - 这个工程非常好,非常快,我真的明白它是什么:) – KenD 2011-03-01 18:01:22

+0

我会改变工会的所有挤出这个查询一点额外:) – luckyluke 2011-03-01 20:15:59

1

存在将短路查询,而不是像加入一样完整遍历表。你也可以重构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))) 
    ) 
3

此查询需要多一点此信息。如果你想以有效的方式编写它,我们需要知道每个负载是否有更多重复或更多新记录。我假设account_id是主键,并有一个聚集索引。

我会使用临时表的做法是创建与phone_no索引的标准化表格r组成和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; 

在这个表上创建非集群索引上的电话号码与第一列第二部分账号。你不能逃避一个全表扫描,所以我假设你可以扫描导入(可能更小)。那么只需加入此表并使用不存在的限定符来解释。当然然后删除该表的处理 卢克