SQL,匹配多个表的行

时间:2011-02-10 20:31:25

标签: sql mysql phpmyadmin

如果我有两张表,A和B的布局相同:

  • 用名字
  • 中间名
  • 出生日期

表A包含我的数据,表B包含我希望与表A进行比较的数据。

我想返回所有完全匹配的匹配(Forename,Middlename和Surname)以及部分匹配(First initial,surname,dob)。

最有效的方法是什么,能够区分这两者?

我最初的想法是,我可以通过两次传递来做到这一点,但是必须有一种更有效的方式,因为在大量记录中这可能是非常低效的。

4 个答案:

答案 0 :(得分:0)

你可以这样做:

select T1.*, T2.*,  'exact-match' as mode
from T1 inner join T2
on T1.fname = T2.fname
and T1.mname = T2.mname
and T1.lname = T2.lname
and t1.dob = T2.dob

UNION

select t1.*, t2.*, 'partial-match' as mode
from T1 inner join T2
on left(T1.fname,1) = LEFT(T2.fname,1)
and T1.lname = T2.lname
and T1.dob = T2.dob
where T1.fname <> T2.fname    

最后一行是因为否则完全匹配也会满足部分匹配测试。如果你愿意,你可以摆脱where子句。查询的第二部分忽略中间名,如果他们出生在同一天,则将“Tim Q Jones”和“Tom X Jones”视为部分匹配。这就是你要求的,对吧?

答案 1 :(得分:0)

如果你真的想避免两个查询,你可以这样做:

SELECT A.*,
       CASE WHEN A.Middlename <> B.Middlename) THEN 'Partial' 
            ELSE 'Full' 
       END AS MatchType
FROM A
JOIN B ON (A.Forename = B.Forename AND
           A.Middlename = B.Middlename AND
           A.Surname = B.Surname)
          OR
          (LEFT(A.Forename,1) = LEFT(B.Forename,1) AND
           A.Surname = B.Surname AND
           A.DoB = B.DoB)  

具有两组不同JOIN条件的JOIN,以及选择中用于标识哪些集必须导致已连接记录的案例(如果Middlename不匹配,则一定不是“完整”匹配这导致了加入)。

答案 2 :(得分:0)

Select 
          T1.Forename
        , T1.Middlename
        , T1.Surname
        , T1.[Date of Birth]
        , Case When T1.[Forename] = T2.[Forename] and T1.Middlename = T2.Middlename
               Then 'Full'
               else 'Partial'
          end as Match_Type
    From Table1 as T1
    Inner Join Table2
    on Left(Table1.[Forename], 1) = Left(Table2.[Forename], 1)
        and Table1.[Date Of Birth] = Table2.[Date Of Birth] 
        and Table1.Surname = Table2.Surname

答案 3 :(得分:0)

这将在一次通过中完成。 识别完整匹配的条件必须是forename and middlename,否则会错误地对某些匹配进行分类。

select Forename, Middlename, Surname, DateOfBirth,
    Case
    when A.ForeName=B.ForeName and A.Middlename = B.middlename then 'full'
    Else 'partial'
    end as MatchType
from A
inner join B on
  -- (Forename, Middlename and Surname)
  (A.ForeName=B.ForeName
  and A.Middlename = B.middlename
  and A.Surname = B.surname)
or
  -- (First initial, surname, dob)
  (A.ForeName LIKE LEFT(B.ForeName,1)+'%'
  and A.Surname = B.surname
  and A.DateOfBirth = B.DateOfBirth)