If I have two tables, A and B which have identical layout of:
Table A contains my data, table B contains data I wish to compare to table A.
I'd like to return all matches that are full matches (Forename, Middlename and Surname) as well as partial matches (First initial, surname, dob).
What would be the most efficient way of doing this and being able to distinguish between the two?
My initial thoughts are that I could do this with two passes however there must be a more efficient way as over a large number of records this could be quite inefficient.
You can do this:
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
The last line is there because otherwise exact matches would also satisfy the partial match test. You can get rid of that where-clause if you like. The second part of the query ignores middle name, and treats "Tim Q Jones" and "Tom X Jones" as a partial-match if they're born on the same day. That's what you asked for, right?
If you really want to avoid two queries, you could do something like this:
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 with two different sets of JOIN criteria, and a case in the select that identifies which of the sets must have resulted in the joined records (If Middlename doesn't match, it must not have been a "full" match that resulted in the join).
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
This will do it in a single pass. The condition for recognizing a full match has to be on both forename and middlename
, otherwise it will classify some matches incorrectly.
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.