2013-05-07 36 views
5

celem zapytania jest również znalezienie możliwych duplikatów nazw, które były błędnie wpisane. Przykład:Dodawanie wielu warunków do MySQL Inner Join

International Group Inc. należy znaleźć jako duplikat International, Group Inc

W celu realizacji tego używanego następnego zapytania:

SELECT C.id, 
     C.name, 
     C.address, 
     C.city_id 
FROM company C 
     INNER JOIN (SELECT name 
        FROM company 
        GROUP BY name 
        HAVING Count(id) > 1) D 
       ON Replace(Replace(C.name, '.', ''), ',', '') = 
        Replace(Replace(D.name, '.', ''), ',', '') 

To działa bardzo dobrze, a wynik był na 40 secs ale dodanie dodatkowy warunek, taki jak AND C.city_id='4' wymaga dodatkowej minuty lub więcej; Jest to nadal akceptowalne, ale nie preferowane.

Mój prawdziwy problem występuje, gdy próbuję dodać kolejny warunek, aby znaleźć tylko duplikaty firm, które mają określony ciąg w nazwie, przy użyciu tego warunku AND C.name LIKE '%International%', to po prostu nie zwraca żadnych wyników.

Czy ktoś może mi pomóc dowiedzieć się, co robię źle?

Dzięki

+0

Niestety, nie sądzę, można efektywnie korzystać z indeksów w tym scenariuszu - chociaż 1 minutę + wydaje się bardzo powolny. – Strawberry

Odpowiedz

6

Ponieważ łączą się w wyniku czynności, zapytanie nie można użyć dowolnego indeksu. Poza tym, koszt wykonania REPLACE() we wszystkich wierszach prawdopodobnie nie jest pomijalny.

Proponuję najpierw dodać indeksowanej kolumny, która otrzymuje „okrojoną” wersję strun, a następnie uruchomić kwerendę z przyłączyć w tej kolumnie:

ALTER TABLE company ADD COLUMN stripped_name VARCHAR(50); 
ALTER TABLE company ADD INDEX(stripped_name); 
UPDATE TABLE company SET stripped_name = REPLACE(REPLACE(name, '.', ''), ',', '') ; 

uruchamiając UPDATE może trwać za pierwszym razem, ale można również ustawić wyzwalacze ON UPDATE i ON INSERT na company, aby stripped_name zapełnić i zaktualizować w locie.

+0

To świetny pomysł - i oczywiste (nawet, jeśli o tym nie myślałem!) – Strawberry

+0

To rozwiązanie naprawdę zwiększa wydajność, ale nadal nie mogę uzyskać wyniku, gdy szukam konkretnego ciągu znaków w nazwie firmy przy użyciu 'AND E.stripped_name LIKE '% International%''. Dlaczego to możliwe? – gustyaquino

+1

@gustyaquino Czy na pewno jest pasujący wiersz? Możesz także używać sortowania z rozróżnianiem wielkich i małych liter. Pokaż nam pełną strukturę twojego stołu ('POKAŻ STWÓRZ TABELĘ firmy;') – RandomSeed

0

Spróbuj począwszy od stołu tmp ponieważ foreach wiersz w spółce tabeli tmp zostanie utworzony:

SELECT C.id, 
     C.name, 
     C.address, 
     C.city_id 
FROM (SELECT name 
        FROM company 
        GROUP BY name 
        HAVING Count(id) > 1) D 
INNER JOIN company C  
       ON Replace(Replace(C.name, '.', ''), ',', '') = 
        Replace(Replace(D.name, '.', ''), ',', '')