문제

나는 약 18000개의 행이 있는 테이블을 받았습니다.각 레코드는 한 고객의 위치를 ​​설명합니다.문제는 그 사람이 테이블을 생성할 때 "회사 이름" 필드를 추가하지 않고 "위치 이름" 필드만 추가했으며 한 회사에 여러 위치가 있을 수 있다는 것입니다.

예를 들어, 동일한 고객을 설명하는 몇 가지 레코드는 다음과 같습니다.

위치 테이블

 ID  Location_Name     
 1   TownShop#1        
 2   Town Shop - Loc 2 
 3   The Town Shop     
 4   TTS - Someplace   
 5   Town Shop,the 3   
 6   Toen Shop4        

내 목표는 다음과 같이 만드는 것입니다.

위치 테이블

 ID  Company_ID   Location_Name     
 1   1            Town Shop#1       
 2   1            Town Shop - Loc 2 
 3   1            The Town Shop     
 4   1            TTS - Someplace   
 5   1            Town Shop,the 3   
 6   1            Toen Shop4        

회사 테이블

 Company_ID  Company_Name  
 1           The Town Shop 

"회사" 테이블이 없습니다. 여러 위치를 나타내는 가장 설명적이거나 가장 적합한 위치 이름에서 회사 이름 목록을 생성해야 합니다.

현재 비슷한 위치 이름 목록을 생성한 다음 해당 목록을 직접 살펴봐야 한다고 생각하고 있습니다.

이에 접근하는 방법에 대한 제안을 주시면 감사하겠습니다.

@Neall, 귀하의 의견에 감사드립니다. 하지만 불행히도 각 위치 이름은 서로 다르며 중복된 위치 이름은 없고 유사만 있습니다.따라서 귀하의 문의 결과에서 "repcount"는 각 행에서 1입니다.

@yukondude, 4단계가 내 질문의 핵심입니다.

도움이 되었습니까?

해결책

질문을 업데이트하세요. 사용 가능한 CompanyNames 목록이 있습니까?Levenshtein algo를 사용하여 CompanyNames 목록과 LocationNames 간의 관계를 찾을 수 있기 때문에 묻습니다.


업데이트

회사 이름 목록이 없습니다. 여러 위치를 나타내는 가장 설명적이거나 가장 적합한 위치 이름에서 회사 이름을 생성해야 합니다.

좋아요...이 시도:

  1. 대부분 또는 모두 알파벳 문자로 구성된 LocationNames를 찾아 후보 CompanyNames 목록을 작성합니다.당신이 사용할 수있는 정규 표현식 이를 위해.이 목록을 별도의 테이블에 저장하세요.
  2. 해당 목록을 알파벳순으로 정렬하고 (수동으로) CompanyName이 되어야 하는 항목을 결정합니다.
  3. 각 CompanyName을 각 LocationName과 비교하고 일치 점수를 얻습니다(사용 레벤슈타인 또는 다른 문자열 일치 알고리즘).결과를 별도의 테이블에 저장합니다.
  4. MatchScore < Threshold가 지정된 CompanyName과 일치하는 것으로 간주되지 않도록 임계값 점수를 설정합니다.
  5. CompanyName | LocationName | MatchScore, 실제로 어떤 것이 일치하는지 알아냅니다.MatchScore로 주문하면 프로세스가 덜 고통스러워집니다.

위 작업의 전체 목적은 부품을 자동화하고 문제의 범위를 제한하는 것입니다.완벽하지는 않지만 18K 레코드를 직접 처리하는 수고를 덜 수 있기를 바랍니다.

다른 팁

전에도 이런 일을 해야만 했어요.이를 수행하는 유일한 실제 방법은 다양한 위치를 수동으로 일치시키는 것입니다.데이터베이스의 콘솔 인터페이스와 그룹화 select 문을 사용하세요.먼저 '회사 이름' 필드를 추가하세요.그 다음에:

SELECT count(*) AS repcount, "Location Name" FROM mytable
 WHERE "Company Name" IS NULL
 GROUP BY "Location Name"
 ORDER BY repcount DESC
 LIMIT 5;

목록 상단에 있는 위치가 어떤 회사에 속하는지 파악한 다음 UPDATE로 회사 이름 필드를 업데이트하세요.WHERE "위치 이름" = "위치" 진술.

추신- 회사 이름과 위치 이름을 별도의 테이블로 분리하고 기본 키로 참조해야 합니다.

업데이트:- 와 - 중복은 없나요?당신은 몇 개의 기록을 갖고 있나요?

복잡한 토큰 일치 알고리즘을 추천하려고 했지만 제대로 하기가 정말 까다롭고 데이터에 상관 관계(오타 등)가 많지 않으면 좋은 결과를 얻지 못할 것입니다.

에 일자리를 제출하는 것이 좋습니다 아마존 기계식 터크 인간이 그것을 분류하게 하세요.

이상적으로는 Company라는 별도의 테이블이 필요하고 이 "Location" 테이블에 Company 테이블의 기본 키(아마도 id라고 함)에 대한 외래 키인 company_id 열이 필요할 것입니다.그러면 이 테이블에서 상당히 많은 텍스트 중복을 피할 수 있습니다(18,000개 이상의 행, 정수 외래 키는 varchar 열에 비해 상당한 공간을 절약합니다).

그러나 여전히 Company 테이블을 로드한 다음 이를 Location의 행과 적절하게 연결하는 방법에 직면해 있습니다.일반적인 해결책은 없지만 다음과 같이 뭔가를 할 수 있습니다.

  1. 자동으로 증가하는 ID 열이 있는 Company 테이블을 만듭니다(RDBMS에 따라 다름).
  2. 고유한 회사 이름을 모두 찾아 Company에 삽입합니다.
  3. 현재로서는 NULL을 허용하고 Company.id 열의 외래 키인 Location에 company_id 열을 추가합니다.
  4. Location의 각 행에 대해 해당 회사를 확인하고 해당 행의 company_id 열을 해당 회사의 ID로 업데이트합니다.이것은 아마도 가장 어려운 단계일 것입니다.데이터가 예제에 표시된 것과 같은 경우 다양한 문자열 일치 접근 방식을 사용하여 여러 번 실행해야 할 것입니다.
  5. Location의 모든 행에 company_id 값이 있으면 Company 테이블을 변경하여 company_id 열에 NOT NULL 제약 조건을 추가할 수 있습니다(모든 위치가 ~ 해야 하다 합리적으로 보이는 회사가 있습니다.)

Location 테이블의 복사본을 만들 수 있으면 일련의 SQL 문을 점진적으로 구축하여 company_id 외래 키를 채울 수 있습니다.실수한 경우 다시 시작하여 오류 지점까지 스크립트를 다시 실행할 수 있습니다.

예, 이전 게시물의 4단계는 이상합니다.

무슨 일이 있어도 이 중 일부는 수동으로 수행해야 하지만 대부분은 자동화할 수 있습니다.제공한 예제 위치의 경우 다음과 같은 쿼리는 적절한 company_id 값을 설정합니다.

UPDATE  Location
SET     Company_ID = 1
WHERE   (LOWER(Location_Name) LIKE '%to_n shop%'
OR      LOWER(Location_Name) LIKE '%tts%')
AND     Company_ID IS NULL;

나는 그것이 당신의 예와 일치할 것이라고 믿습니다(나는 IS NULL 이전에 설정된 Company_ID 값을 덮어쓰지 않는 부분). 물론 18,000개의 행에서 다양한 조합을 처리하려면 꽤 창의적이어야 합니다.

도움이 될 수 있는 또 다른 방법은 Company의 이름을 사용하여 위와 같은 쿼리를 생성하는 것입니다.다음과 같은 작업을 수행할 수 있습니다(MySQL에서).

SELECT  CONCAT('UPDATE Location SET Company_ID = ',
        Company_ID, ' WHERE LOWER(Location_Name) LIKE ',
        LOWER(REPLACE(Company_Name), ' ', '%'), ' AND Company_ID IS NULL;')
FROM    Company;

그런 다음 생성된 명령문을 실행하십시오.그것은 당신을 위해 많은 그런지 작업을 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top