SQL, сопоставление строк в нескольких таблицах - PullRequest
0 голосов
/ 10 февраля 2011

Если у меня есть две таблицы, A и B, которые имеют одинаковое расположение:

  • Имя
  • Мидл-имя
  • Фамилия
  • ДатаРождение

Таблица A содержит мои данные, таблица B содержит данные, которые я хочу сравнить с таблицей A.

Я хочу вернуть все совпадения, которые являются полными (Forename, Middlenameи фамилия), а также частичные совпадения (первая инициализация, фамилия, доб).

Каков был бы наиболее эффективный способ сделать это и иметь возможность различать два?

Мои первоначальные мысли заключались в том, что я мог бы сделать это за два прохода, однако должен быть более эффективный способ, поскольку при большом количестве записей это может быть весьма неэффективно.

Ответы [ 4 ]

0 голосов
/ 11 февраля 2011

Это будет сделано за один проход.Условие для распознавания полного совпадения должно быть на обоих 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)
0 голосов
/ 11 февраля 2011

Если вы действительно хотите избежать двух запросов, вы можете сделать что-то вроде этого:

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 и регистр в select, который определяет, какой из наборовдолжно привести к объединенным записям (если Middlename не совпадает, это не должно быть "полное" совпадение, которое привело к объединению).

0 голосов
/ 11 февраля 2011
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 голосов
/ 11 февраля 2011

Вы можете сделать это:

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, если хотите. Вторая часть запроса игнорирует отчество и рассматривает «Тим К Джонс» и «Том Х Джонс» как частичное совпадение, если они родились в один день. Это то, что вы просили, верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...