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

  • Имя
  • Второе имя
  • Фамилия
  • Дата рождения

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

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

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

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

0
Mike 10 Фев 2011 в 23:31
1
Почему у вас два одинаковых макета таблицы?
 – 
Daniel A. White
10 Фев 2011 в 23:32
Чтобы найти совпадения между ними.
 – 
Mike
10 Фев 2011 в 23:33
Я думаю, Даниал А. Уайт имеет в виду: почему бы тогда не поместить это в одну таблицу?
 – 
GolezTrol
10 Фев 2011 в 23:34
Означает ли first initial [имя + инициал (первая буква середины)] или что-то еще?
 – 
RichardTheKiwi
11 Фев 2011 в 00:20
Первый инициал должен был быть первой буквой имени, извиняюсь, что не прояснил это.
 – 
Mike
11 Фев 2011 в 00:24

4 ответа

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

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» как частичное совпадение, если они родились в один и тот же день. Это то, что вы просили, верно?

0
Tim 11 Фев 2011 в 00:57

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

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)  

СОЕДИНЕНИЕ с двумя разными наборами критериев СОЕДИНЕНИЯ и случай в выборе, который определяет, какой из наборов должен был привести к объединенным записям (если отчество не совпадает, это не должно быть «полное» совпадение, которое привело к присоединение).

0
Dan J 11 Фев 2011 в 00:59

Это будет сделано за один проход. Условие для распознавания полного совпадения должно быть на обоих 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
RichardTheKiwi 11 Фев 2011 в 01:05
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
JeffO 11 Фев 2011 в 06:28
Разве это не исключает «частичные» совпадения? OP определяет частичные совпадения как те, в которых отчество не совпадает, среди прочего.
 – 
Dan J
11 Фев 2011 в 00:58