用于不同记录比较的Sql

用于不同记录比较的Sql,sql,Sql,我将一个表与它自身进行比较,试图确定一条记录中的电子邮件是否正在另一条记录的其他四列中的任何一列中使用 为了简化此过程,让我们看一个简化的示例: Name: Bob Office Email: bob@aaa.com Home Email: bob@home.com Mobile Email: bobster@gmail.com 现在我有一个sql语句,如下所示: select c1.ContactId id1, c1.FullName Name1, 'Office Email 1' Ema

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

为了简化此过程,让我们看一个简化的示例:

Name: Bob
Office Email: bob@aaa.com
Home Email: bob@home.com
Mobile Email: bobster@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的电子邮件中重复

我只需要一张唱片。我相信这是一个常见的问题,但我不太知道如何描述这个问题,足以让搜索引擎返回有用的东西


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

问题的解决方案是添加条件:c1.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

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


从u.user\u id=ci上的user u LEFT JOIN contactinfo ci中选择user.username。user\u id LEFT JOIN contacttype ct ON ci。type\u id=ct.type\u id GROUP BY ci。countvalue>1的值将是查找任何重复源的查询

如果您能够规范化数据库,请执行此操作。联系人和电子邮件地址之间的一对多关系是合适的。然后,您可以在电子邮件地址和类型上输入一个唯一的contstraint。另外,如果鲍勃和罗布真的有相同的家庭电子邮件呢?我妻子和我都有。不幸的是,我无法正常化数据库,我正在与MS CRM 2011合作,这些电子邮件除了一封之外都很好,但在这一点上,这是无关紧要的。非常酷的方法。非常感谢,我会尝试它,如果它做了我认为它做的,我会标记为解决方案很快。很好,结合您的建议,使它既快速又准确。我真希望能给你买杯啤酒!不幸的是,我无法正常化数据库,我正在与MS CRM 2011合作,这些电子邮件除了一封外都很好,但在这一点上,这是不相关的。
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