Sql用于不同的记录比较

时间:2013-04-17 19:36:08

标签: sql

我正在比较一个表本身,试图确定一条记录中的电子邮件是否正在另一条记录中的其他四列中的任何一列中使用。

为了使这更容易,让我们看一个例子(简化):

Name: Bob
Office Email: bob@aaa.com
Home Email: bob@home.com
Mobile Email: bobster@gmail.com

Name: Rob
Office Email: rob@bbb.com
Home Email: bob@home.com
Mobile Email: robert@gmail.com

现在我有一个像这样的sql语句:

select c1.ContactId id1, c1.FullName Name1, 'Office Email 1' EmailType1, c1.EMailAddress1 Email, 
   c2.ContactId id2, c2.FullName Name2, 
   CASE c1.EmailAddress1
    WHEN c2.EMailAddress1 THEN 'Office Email 1'
    WHEN c2.Si_OfficeEmail2nd THEN 'Office Email 2'
    WHEN c2.EMailAddress2 THEN 'Mobile Email'
    WHEN c2.pc_hmemail THEN 'Home Email'
    ELSE '?'
   END EmailType2,
   CASE c1.EmailAddress1
    WHEN c2.EMailAddress1 THEN c2.EMailAddress1
    WHEN c2.Si_OfficeEmail2nd THEN c2.Si_OfficeEmail2nd
    WHEN c2.EMailAddress2 THEN c2.EMailAddress2
    WHEN c2.pc_hmemail THEN c2.pc_hmemail
    ELSE '?'
   END DuplicateEmail
from Contact c1, Contact c2
where (
   LTRIM(RTRIM(c1.EMailAddress1 )) = LTRIM(RTRIM(c2.EMailAddress1))
Or LTRIM(RTRIM(c1.EMailAddress1 )) = LTRIM(RTRIM(c2.EMailAddress2))
Or LTRIM(RTRIM(c1.EMailAddress1 )) = LTRIM(RTRIM(c2.pc_hmemail))
Or LTRIM(RTRIM(c1.EMailAddress1 )) = LTRIM(RTRIM(c2.Si_OfficeEmail2nd))
)
And c1.ContactId <> c2.ContactId
And c1.StateCode = 0 
and c2.StateCode = 0
order by c1.FullName, c2.FullName

不幸的是,因为Bob和Rob有相同的电子邮件'类型'(家庭电子邮件)由于拼写错误而重复,我的查询返回两条记录,一条显示Bobs电子邮件在Robs电子邮件中重复,另一条记录Robs电子邮件在Bobs电子邮件中重复。

我只需要一条记录。我确信这是一个常见的问题,但我不太清楚如何很好地描述这个问题,让搜索引擎返回一些有用的东西。

也许有更好的方法来解决这个问题?如果没有,除了跳过一堆中间临时表以消除这些等效记录之外,有没有办法为此编写单个查询?

2 个答案:

答案 0 :(得分:1)

问题的解决方案是添加条件:c1.contactId < c2.ContactId。这会限制您正在查看的对。

如果您正在查看电子邮件,您可能会找到一种更快速查看电子邮件的方法。类似下面的内容将返回所有重复的电子邮件:

select e.*
from (select e.*, COUNT(*) over (partition by email) as NumTimes
      from ((select contactId, 'Office' as which, EmailAddress1 as email
             from Contact
            ) union all
            (select contactId, 'Office2', Si_OfficeEmail2nd
             from Contact
            ) union all
            (select contact_id, 'Home', pc_hmemail
             from Contact
            ) union all
            (select contact_id, 'Mobile', EmailAddress2
             from Contact
            )
           ) e
      where email is not null and email <> ''
     ) e
where NumTimes > 1
order by email

答案 1 :(得分:0)

我首先建议继续规范化您的数据结构。一个人可能有几种类型的联系信息。因此,personID,typeID和value可以放在另一个表中。在此表中,您可以创建与类型表的另一种关系,您可以在其中跟踪不同的联系类型(例如,家庭电子邮件,工作电子邮件,Twitter,链接,Facebook等)。它不仅可以提高系统的可扩展性,还可以更有效地运行这些类型的查询。

SELECT user.username FROM user u LEFT JOIN contactinfo ci ON u.user_id=ci.user_id LEFT JOIN contacttype ct ON ci.type_id=ct.type_id GROUP BY ci.value HAVING count(value)>1将是查找任何重复来源的查询