2012-03-27 2 views
6

나는 몇 달 전에 비슷한 질문을했다. 여기에 위치 : MySQL Query based on stringMySQL 문자열 비교

나는이 문제가 단지 하나의 특정 순서로 작동하고 어떤 경우에는 너무 잘 작동한다는 점에 착수하고 있습니다. 여기

는 (중복이 실제 데이터를위한 것)이 쿼리 필터링 된 데이터의 조각입니다 :

내 마지막 질문 ( MySQL Query based on string)에 도움이 한 쿼리가 하나의 예를 들어 잘 작동
- BELLMORE 
- ATLANTIC BCH 
- ATLANTIC BEACH 
- E HILLS 
- EAST HILLS 
- EAST ROCKAWAY 
- FAR ROCKAWAY 
- FLORAL PARK 
- FLORAL PARK 
- HIGHLAND HEIGHTS 
- N HIGHLAND HGTS 
- NORTH HIGHLAND HEIGHTS 

다른 인스턴스에 대해 실패했습니다.

select names from tablename group by substring_index(names," ",1) 

반환 다음은 쿼리입니다

- BELLMORE 
- ATLANTIC BEACH 
- EAST HILLS 
- FAR ROCKAWAY 
- FLORAL PARK 
- HIGHLAND HEIGHTS 
- N HIGHLAND HGTS 
- NORTH HIGHLAND HEIGHTS 

하나의 문제는 당신이 볼 수 있듯이 그것이 첫 번째 단어를 사용했기 때문에 그것을하지 말았어야하는 도시를 제거한다는 것입니다 그룹화 할 수 있습니다. 삭제 된 항목은 다음과 같습니다.

- EAST ROCKAWAY 

이스트가 GROUP'ed BY EAST입니다.

정적 인 도시 이름과 가변 부분의 위치가 항상 변하기 때문에 나는 이것을 거의 쓰지 않는다고 생각합니다. 특정 양의 문자를 비교할 수없는 경우. 멀리까지 완벽하지는 않습니다. 누군가가 그들이 어떤 통찰력을 가지고 있다고 생각하거나 그러한 일을 수행하고 성취했다면 나는 피드백과 지침을 높이 평가할 것입니다.

- BELLMORE 
- ATLANTIC BEACH 
- EAST HILLS 
- EAST ROCKAWAY 
- FAR ROCKAWAY 
- FLORAL PARK 
- HIGHLAND HEIGHTS 
+1

'N'= '북쪽', 'Hghts' ='등의 공통 동의어 목록을 수동으로 생성 할 수 있습니까? Heights' 등 – mellamokb

답변

2

나의 제안은 비싼 쿼리 수 있지만 그것이 모든 시간을 요구하지 않도록 희망 당신은 당신의 데이터를 가끔 "청소"를 수행 할 작업의 유형을 사용할 수 있습니다 끝 결과는 것 이 데이터를 쿼리합니다.

두 시퀀스 간의 차이를 측정하기위한 문자열 메트릭 인 Levenshtein distance 수식을 살펴 보는 것이 좋습니다.

테이블의 직교 제품에 대한 거리를 계산할 필요가 없도록하려면 먼저 동일한 문자로 시작하는 것과 같은 빠른 성의 체크와 비교할 도시와 주소 집합을 좁힐 수 있습니다 , 그리고 비슷한 길이.

처음에, 당신은 만 ... 그런 다음 일치 한 변화를 선택 할 수있는 아주 작은 Levenshtein 거리 레코드를 반환하여 시작할 수있는 것은 데이터를 정상화하기 위해 다른 기록에 적용 반환 .

너무 많은 오 탐지를 받기 시작할 때까지 점차적으로 거리를 늘릴 수 있습니다.

Here's an implementation directly in MySql :

CREATE FUNCTION levenshtein(s1 VARCHAR(255), s2 VARCHAR(255)) 
    RETURNS INT 
    DETERMINISTIC 
    BEGIN 
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT; 
    DECLARE s1_char CHAR; 
    -- max strlen=255 
    DECLARE cv0, cv1 VARBINARY(256); 
    SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0; 
    IF s1 = s2 THEN 
     RETURN 0; 
    ELSEIF s1_len = 0 THEN 
     RETURN s2_len; 
    ELSEIF s2_len = 0 THEN 
     RETURN s1_len; 
    ELSE 
     WHILE j <= s2_len DO 
     SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1; 
     END WHILE; 
     WHILE i <= s1_len DO 
     SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1; 
     WHILE j <= s2_len DO 
      SET c = c + 1; 
      IF s1_char = SUBSTRING(s2, j, 1) THEN 
      SET cost = 0; ELSE SET cost = 1; 
      END IF; 
      SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost; 
      IF c > c_temp THEN SET c = c_temp; END IF; 
      SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1; 
      IF c > c_temp THEN 
       SET c = c_temp; 
      END IF; 
      SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1; 
     END WHILE; 
     SET cv1 = cv0, i = i + 1; 
     END WHILE; 
    END IF; 
    RETURN c; 
    END; 
+0

이것이 어떻게 작동하는지 모르겠다. 'N HIGHLAND HGTS'와 'NORTH HIGHLIGHTS HEIGHTS'의 거리를 7로 계산하지 않고, 'EAST ROCKAWAY'와 'FAR ROCKAWAY'의 거리를 4로 계산하지 않을 것인가? 선택한 모든 거리에 대한 위양성/위음성 수. – mellamokb

+0

@mellamokb 당신은 절대적으로 옳습니다 ... 그의 샘플 데이터를보다 면밀히 살펴보면, 당신이 제안한 공통 동의어와 함께 사용하면 가능할 것입니다. –

1

Toughie ... 나는 확실히 마이클의 제안을 활용하고로 데이터베이스에 독특한 장소의 이름을 유지의 가능성을 던져 줄

.

이렇게하면 새 장소 추가시 문자열 거리 계산 만 사용할 수 있습니다. 그런 다음 levenshtein이 식별하는 장소에 associate_id를 할당하여 작업 공간을 관리 할 수 ​​있습니다.

아마도 다른 데이터 (예 : 위치 정보)를 사용하여 장소를 연결하는 방법을 더 자세히 조정할 수 있습니다. 최대 촬영은 단지 장소 이름을 사용하는 것이 문제의 최선의 해결책이 아닐 수도 있습니다 ...