2009-10-07 2 views
2

(주로) SQL을 사용하여 두 개의 개별 시스템간에 사람들을 대응시키는 방법이 있는지 알고 싶습니다.SQL을 사용하여 개별 시스템간에 사람들을 일치시키는 방법은 무엇입니까?

사람이 저장된 두 개의 Oracle 데이터베이스가 있습니다. 둘 사이에 링크가 없습니다 (즉, person_id에 가입 할 수 없음). 이것은 의도적 인 것입니다. 시스템 A의 주어진 그룹의 사람들이 시스템 B에 있는지 확인하는 쿼리를 작성하려고합니다.

테이블을 쉽게 만들 수 있으면 만들 수 있습니다. 또한 최종 보고서를 만들 때 쿼리를 실행하고 Excel에서 데이터 조작을 수행 할 수도 있습니다. 나는 PL/SQL에 익숙하지 않다.

시스템 A에서 우리는 사람들에 관한 정보 (이름, DOB, 성별, 성별 등)를 가지고 있습니다. 시스템 B에는 사람들에 관한 동일한 유형의 정보가 있습니다. 데이터 입력 오류가있을 수 있습니다 (사람이 잘못된 철자를 입력 함). 그러나 처음 네 글자를 비교하는 것 외에는 너무 많이 걱정하지 않을 것입니다. This question deals with that problem more specifically.

이 방법은 상관 관계가있는 하위 쿼리를 사용하는 것으로 생각했습니다. 그래서, 약,

select a.lastname, a.firstname, a.soc, a.dob, a.gender 
    case 
    when exists (select 1 from b where b.lastname = a.lastname) then 'Y' else 'N' 
    end last_name, 
    case 
    when exists (select 1 from b where b.firstname = a.firstname) then 'Y' else 'N' 
    end first_name, 
    case [etc.] 
from a 

이 나는 ​​Excel로 결과를 내 보낸 다음 3 개 이상 일치가 기록을 찾을 수 있습니다 ... 내가 생각하기에, 원하는 걸 수 있습니다. 나는 이것이 A의 주어진 필드가 B.에서 발견되었다고 믿습니다. 그러나이 필드 중 세 개만으로이 쿼리를 실행했고 실행하는데 3 시간 이상이 걸렸습니다 (2 년간의 데이터를보고 있음). 최대 5 개의 기준 (성, 이름, 성별, 생년월일, soc)을 일치시킬 수 있기를 바랍니다. 또한 soc 번호가 일치하는 데 가장 적합한 선택이지만 가장 자주 누락되는 경향이있는 데이터 조각이기도합니다. 이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 감사.

+0

HLGEM 및 rexem과 마찬가지로 하위 쿼리가 아닌 조인을 사용하는 것이 좋습니다. 또한 아직 수행하지 않은 경우 데이터를 하나의 데이터베이스로 복사하여 성능을 향상시킬 수 있습니다. –

답변

1

당신은 분명히 다른 경기의 무게를 달아야합니다. SSN이 일치하면 꽤 좋은 징후입니다. firstName이 일치하면 기본적으로 쓸모가 없습니다.

링크 된 소리 나는 문자열 일치 알고리즘과 결합 된 일치 항목의 가중치를 기반으로 점수를 매길 수 있습니다. 다음은 T-SQL에서 수행 한 예제입니다. 문제를 해결하기 위해 오라클에 포팅해야합니다.

--Score Threshold to be returned 
DECLARE @Threshold DECIMAL(5,5) = 0.60 

--Weights to apply to each column match (0.00 - 1.00) 
DECLARE @Weight_FirstName DECIMAL(5,5) = 0.10 
DECLARE @Weight_LastName DECIMAL(5,5) = 0.40 
DECLARE @Weight_SSN DECIMAL(5,5) = 0.40 
DECLARE @Weight_Gender DECIMAL(5,5) = 0.10 

DECLARE @NewStuff TABLE (ID INT IDENTITY PRIMARY KEY, FirstName VARCHAR(MAX), LastName VARCHAR(MAX), SSN VARCHAR(11), Gender VARCHAR(1)) 
INSERT INTO @NewStuff 
    (FirstName, LastName, SSN, Gender) 
VALUES 
    ('Ben','Sanders','234-62-3442','M') 

DECLARE @OldStuff TABLE (ID INT IDENTITY PRIMARY KEY, FirstName VARCHAR(MAX), LastName VARCHAR(MAX), SSN VARCHAR(11), Gender VARCHAR(1)) 
INSERT INTO @OldStuff 
    (FirstName, LastName, SSN, Gender) 
VALUES 
    ('Ben','Stickler','234-62-3442','M'), --3/4 Match 
    ('Albert','Sanders','523-42-3441','M'), --2/4 Match 
    ('Benne','Sanders','234-53-2334','F'), --2/4 Match 
    ('Ben','Sanders','234623442','M'), --SSN has no dashes 
    ('Ben','Sanders','234-62-3442','M') --perfect match 

SELECT 
    'NewID' = ns.ID, 
    'OldID' = os.ID, 

    'Weighted Score' = 
     (CASE WHEN ns.FirstName = os.FirstName THEN @Weight_FirstName ELSE 0 END) 
     + 
     (CASE WHEN ns.LastName = os.LastName THEN @Weight_LastName ELSE 0 END) 
     + 
     (CASE WHEN ns.SSN = os.SSN THEN @Weight_SSN ELSE 0 END) 
     + 
     (CASE WHEN ns.Gender = os.Gender THEN @Weight_Gender ELSE 0 END) 
    , 

    'RAW Score' = CAST(
     ((CASE WHEN ns.FirstName = os.FirstName THEN 1 ELSE 0 END) 
     + 
     (CASE WHEN ns.LastName = os.LastName THEN 1 ELSE 0 END) 
     + 
     (CASE WHEN ns.SSN = os.SSN THEN 1 ELSE 0 END) 
     + 
     (CASE WHEN ns.Gender = os.Gender THEN 1 ELSE 0 END)) AS varchar(MAX)) 
     + 
     '/4', 

    os.FirstName , 
    os.LastName , 
    os.SSN , 
    os.Gender 

FROM @NewStuff ns 

--make sure that at least one item matches exactly 
INNER JOIN @OldStuff os ON 
    os.FirstName = ns.FirstName OR 
    os.LastName = ns.LastName OR 
    os.SSN = ns.SSN OR 
    os.Gender = ns.Gender 
where 
    (CASE WHEN ns.FirstName = os.FirstName THEN @Weight_FirstName ELSE 0 END) 
    + 
    (CASE WHEN ns.LastName = os.LastName THEN @Weight_LastName ELSE 0 END) 
    + 
    (CASE WHEN ns.SSN = os.SSN THEN @Weight_SSN ELSE 0 END) 
    + 
    (CASE WHEN ns.Gender = os.Gender THEN @Weight_Gender ELSE 0 END) 
    >= @Threshold 
ORDER BY ns.ID, 'Weighted Score' DESC 

그리고 출력은 다음과 같습니다.

NewID OldID Weighted Raw First Last  SSN   Gender 
1  5  1.00000 4/4 Ben Sanders 234-62-3442 M 
1  1  0.60000 3/4 Ben Stickler 234-62-3442 M 
1  4  0.60000 3/4 Ben Sanders 234623442 M 

그런 다음 가능한 각 일치의 유효성을 평가하기 위해 몇 가지 사후 처리를 수행해야합니다. 가중 점수를 얻기 위해 1.00을 얻은 경우 두 가지를 얻지 않는 이상 올바른 일치라고 가정 할 수 있습니다. 성과 이름 (SSN) (예를 들어, 합산 된 가중치가 0.8 인 경우)이 맞는 것으로 합리적으로 확신 할 수 있습니다.

+0

SQL Server 표기법 (가능하면 MySQL도 가능), Oracle ... –

+0

It 하지만, 이식 될 수 있다고 상상합니다. 나는 이것을 개념으로 올리려고했다. – EndangeredMassa

+0

감사합니다. 매우 도움이 될 것 같습니다. PL/SQL에 익숙하지 않아서이 작업을 수행 할 수 있는지 여부를 확인하는 데 시간이 걸릴 수 있습니다. 그러나 나는 무슨 일이 일어나고 있는지 이해하고있다. 감사! – Julie

0

WHERE 절의 테이블 b에있는 모든 열에 인덱스가 있습니까? 그렇지 않으면 테이블 a의 각 행에 대해 테이블을 완전히 검색합니다.

+0

a) WHERE 절 없음 b) 현재의 방식이 매우 느리고 다른 제안을 찾고 있음을 이해합니다. 나는 여기에서 아주 새롭고 데이터베이스 설계에 완전히 익숙하지 않다. 감사! – Julie

+0

예, 각 CASE 식 SELECT 문에는 WHERE 절이 있습니다. – DCookie

+0

b) 테이블 b의 열을 적절하게 색인화하면 쿼리 속도가 상당히 빨라집니다. – DCookie

2

상관 관계가있는 하위 쿼리 대신 조인을 사용 하겠지만 모든 필드에 조인해야하므로 항목을 향상시킬 수있는 정도를 알 수 없습니다. 하지만 상관 관계가있는 하위 쿼리는 행 단위로 평가해야하기 때문에 조인을 사용하지 않아도 좋은 인덱싱을 사용하면 좋은 결과를 얻을 수 있습니다. 그러나 모든 성능 튜닝과 마찬가지로 테크니크 만 시도하면 확실히 알려줄 것입니다.

SQL Server 시스템에서 중복 된 작업을 찾고 비슷한 단계로 나눴습니다. 그래서 처음에는 이름과 도시/주가 정확히 일치하는 모든 사람들을 찾았습니다. 그런 다음 추가 가능한 일치 항목 (전화 번호, ssn, 정확하지 않은 이름 일치 등)을 찾았습니다. 두 프로필간에 가능한 일치가 발견되면 일치하는 유형의 코드가있는 준비 테이블에 추가했습니다. 각 유형의 성냥에 대한 자신감을 더하고 각각의 잠재적 인 성냥에 대한 자신감을 더했습니다. 그래서 SOC가 일치하면 높은 확신을 얻습니다. 이름이 eact이고 성별이 정확하고 dob가 정확한 경우 동일합니다. 마지막 이름은 정확하고 이름은 정확하지 않습니다. 자신감을 추가함으로써 어떤 사람이 같은 사람이 될 가능성이 더 큰지를 훨씬 더 잘 볼 수있었습니다 .SQl 서버에는 soundex 함수가 있습니다. 다소 차이가있는 이름입니다. 오라클과 비슷한 점이 있다고 생각합니다.

이 작업을 수행 한 후 SSIS에서 퍼지 그룹화를 수행하는 방법을 배웠고 더 많은 일치 항목을 생성 할 수있었습니다. h 높은 신뢰 수준. 나는 오라클의 ETL 툴이 퍼지 로직을 수행하는 방법을 가지고 있는지 모르지만, 그렇게한다면 이러한 유형의 태스크에 도움이 될 수 있습니다. SQL Server를 사용하면 SSIS를 Oracle에 연결하여 실행할 수 있으므로 혼자 퍼지 그룹을 사용할 수 있습니다. 실행하는 데 시간이 오래 걸릴 수 있습니다.

성함, 성 (dob) 및 성별이 동일인임을 보장합니다.

+0

"상관 된 하위 쿼리 대신 조인을 사용할 것입니다."- hm. 나는 이것에 익숙하지 만, 나는 두 테이블에 합류 할 수 없다고 생각한다. 개인 ID가 두 시스템을 연결할 수 없다는 시스템 요구 사항이 있습니다. 내가 사용할 수 있다고 생각되는 유일한 유일한 ID는 soc이지만, 내가 말했듯이, 그것은 많이 빠져있다. "처음에는 이름과 도시/주가 정확히 일치하는 모든 사람을 찾았습니다." - 어떻게 한거야? "경고 할 것입니다 ..."이것은 잘못된 데이터로 인해 우리가 겪고있는 문제입니다. 보고서를 요청하는 사람들은 이것을 알고 있습니다. 감사합니다. – Julie

+0

Oracle 8i +는 SOUNDEX를 지원합니다 : http://techonthenet.com/oracle/functions/soundex.php –

+0

당신은 personid에 가입하지 않으므로 일치하려는 파일에 가입하십시오. 테이블 1에서 선택 * t1.firstname = t2.firstname 및 t1.lastname = t2.lastname 및 t1.DOB = t2.DOB에 테이블 1 t1 조인 table2 t2 – HLGEM

2

HLGEM의 가입 제안의 예 :

SELECT a.lastname, 
     a.firstname, 
     a.soc, 
     a.dob, 
     a.gender 
    FROM TABLE a 
    JOIN TABLE b ON SOUNDEX(b.lastname) = SOUNDEX(a.lastname) 
       AND SOUNDEX(b.firstname) = SOUNDEX(a.firstname) 
       AND b.soc = a.soc 
       AND b.dob = a.dob 
       AND b.gender = a.gender 

참조 : SOUNDEX

+0

감사합니다. 의미가 있지만 데이터가 너무 지저분하고 아무 것도 반환되지 않습니다! soundex 함수의 사용법을 보여 주셔서 감사합니다. 실제로 사용 된 방법을 잘 모르겠습니다. – Julie

관련 문제