2011-02-10 50 views
0

如果我有兩個表,A和B具有相同的佈局:SQL,匹配的行跨多個表

  • 用的名字
  • 中間名
  • 出生日期

表A包含我的數據,表B包含我希望與表A比較的數據。

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

什麼是最有效的方式來做到這一點,並能夠區分兩者?

我最初的想法是我可以通過兩遍來做到這一點,但是必須有更有效的方式來處理大量的記錄,這可能是非常低效的。

+1

爲什麼你有兩個相同的表格佈局? –

+0

查找它們之間的匹配。 – Mike

+0

我覺得Danial A. White的意思是:爲什麼不把它放在一張桌子上呢? – GolezTrol

回答

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-clause。查詢的第二部分忽略中間名,如果他們出生在同一天,則將「Tim Q Jones」和「Tom X Jones」視爲部分匹配。這就是你要求的,對吧?

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) 

A JOIN有兩套不同的連接標準的,並且在選擇的情況下,識別哪一組必須導致了連接的記錄(如果Middlename不匹配,它不能是導致連接的「完整」匹配)。

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

這不會排除「部分」匹配嗎? OP將部分匹配定義爲中間名*不匹配的部分匹配等等。 –

+0

@djacobson - 好。問題改變了嗎? – JeffO

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)