2011-01-08 2 views
0

이 흥미로운 정보를 얻길 바랍니다! C#은 솔루션 또는 T-SQL에서 선호되는 언어입니다."유사한"부품 번호 찾기

항목 1 :

은 다음 항목을 고려 NJ2-12GM50-WO-V13을

항목 2 :

당신은 추측 할 수 NJ2-12GM50-WO-V13 그 각각의 진입 항목 (1) 아이템 2에 들어가는 사람은 방금 찾은 가장 가까운 영어 문자 인 'o'를 사용했습니다.

누군가 NJ2-12GM50-Wo-V13과 같은 새 부품 번호를 입력하면 NJ2-12GM50-Wö-V13을 의미 할 수도 있음을 제안하고자합니다.

이렇게하기 위해 VARCHAR로 저장할 수있는 모든 문자를 단순한 소문자로 다시 변환하려고합니다. 예를 들어 ASCII 문자 246 (ö)을 ASCII 문자 111 (o)로 변환하는 솔루션에 관심이 있습니다.

부품 번호의 변환 된 버전이 모두 들어있는 조회 열을 만들면 키보드 입력과 쉽게 일치시킬 수 있습니다.

물론 사전을 만들 수는 있지만 똑똑한 방법이 있는지 궁금합니다.

감사합니다.

+0

아래에서 언급 한 것처럼 사용자와 얼마나 멀리 떨어져 있는지 고려해야합니다 갈 수 있습니다. 간단한 e 대 é가 한 가지입니다. 그러나 "가까운"숫자는 또 다른 숫자입니다. 관심사로서, 맞춤법 검사기 (SOUNDEX (또는 빅 브라더, 이중 메타 폰))를 사용합니다. 그러나 그것은 심각 해지고있다;) – IamIC

답변

2

아마도 두 가지 부품 번호 사이에 Levenshtein distance을 계산하기 위해 C# 또는 T-SQL에 함수를 구현하는 것이 가장 좋습니다.

+0

이것은 과잉이 아닌가? 분명히 간단한 "COLLATE"가 SQL에서 특히 그러하다. – gbn

+0

@gbn - 아마도. 차이의 유형에 따라 다릅니다. 예, 유일한 차이가'o'와'ö' 인 경우 collate는 라틴어를 가정하고 collate 된 결과에서 시스템이 일치하는 것을 발견하고 누락 된 문자와 같은 다른 차이점이 없다고 가정 할 것입니다. – Thomas

+0

이것은 매우 도움이되었으며 제안에 감사드립니다. 부품 번호가 11,000,000 개 이상인 행에 대해 언급하지 않았습니다. 우리가 한 일은 결국 각 파트 번호를 4 개의 문자 시퀀스로 "토큰 화"하는 것이 었습니다 ... 그래서 ROCKY는 '바위'와 'ocky'입니다. 가능한 모든 4 문자 시퀀스를 "토큰"테이블에 넣고 ItemsTokens라는 많은 테이블을 생성합니다.이 테이블에는 두 ID에 복합 키가 있습니다. 트리거는 항목을 토큰 화 된 상태로 유지합니다.그것은 우리에게 너무 많은 결과를 주지만, 빠릅니다. 그런 다음 Levenshtein을 초기 결과에 사용하여 충분히 가깝지 않은 경기를 버립니다. –

1

어떤 이유에서든이 내용을 주석으로 추가 할 수는 없지만 "일반적으로 검색 한"매핑과 일치하는 것으로 간주 할 수 있습니다. 이러한 시스템은 일반적으로 유용 할 수 있으며 (예 : "빨간색 옷걸이 -> AB-999X"등)이 문제를 해결할 수 있습니다. 어쨌든 고려할만한 가치가 있습니다.

+0

이것은 "equivelant"로 알려진 것들을 실제로 매핑하는 데 매우 유용합니다. 예를 들어 MyCompany Ltd, MyCompany Limited, MyCompany Ltd., MyCompany Limited., MyCompany Limted (typo) 등 ...이 회사, Limited, Ltd. 등의 모든 회사 이름을 사용할 수 있습니다. 우리는 그것을 반드시 고려해야합니다. 좋은 코멘트, 고마워!. –

2

IF 'NJ2-12GM50-Wö-V13' COLLATE Latin1_General_CI_AI 
     = 
    'NJ2-12GM50-Wo-V13' COLLATE Latin1_General_CI_AI 
     PRINT 'matches' 
ELSE 
     PRINT 'no match 

그래서 케이스를 구분 악센트 모두 문자열을 강요하는 COLLATE 절을 사용하여, 당신은 뭔가 당신이 할 수있는 다른 COLLATE를 사용하여 사용자 입력

SELECT 
    PartNo AS DidYouMeanThis, 
    @Input AS WhenYouEnteredThis 
FROM 
    MyPartNumbers 
WHERE 
    PartNo COLLATE Latin1_General_CI_AI = @Input COLLATE Latin1_General_CI_AI 

의 유효성을 검사처럼 사용할 수 있습니다 쓰기에 정확한 일치를 보장하십시오.

IF NOT EXISTS (SLECT * FROM MyPartNumbers 
      WHERE PartNo COLLATE Latin1_General_BIN = @Input Latin1_General_BIN) 
    RAISERROR ('Oi! I asked DidYouMeanThis', 16, 1) 
ELSE 
    INSERT ... 
+0

아마도 라틴 문자를 가정하고 국제 문자의 사용을 가정하는 가장 간단한 해결책이 유일한 차이 일 것입니다. – Thomas

+0

이것은 좋은 제안이었고 내 표를 얻었다. 감사! 유감 스럽지만 각 문자열을 비교하기에는 너무 많은 항목 (11,000,000 개 이상)이 있으며 정확한 일치는 사용하지 않습니다. 그러나 일단 부품 번호를 토큰 화하면 (위의 주석 참조) 추악한 String.Replace 작업을 먼저 수행 할 필요없이 토큰 테이블에서 들어오는 문자열에서 파생 된 토큰을 일치시키기 위해 COLLATE를 사용할 수 있습니다. ASCII 문자 목록에있는 소수의 예외만으로도 훌륭하게 작동합니다 ... 아마 5 정도, 우리는 개별적으로 처리합니다. –