2013-05-07 29 views
5

hinzufügen Das Ziel der Abfrage ist es auch, mögliche Duplikate von Namen zu finden, die falsch eingegeben wurden. Beispiel:Mehrere Bedingungen zu MySQL Inner Join

International Group Inc. muss als Duplikat International, Group Inc

Um diese einen verwendet, um die nächste Abfrage zu erreichen finden werden:

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, '.', ''), ',', '') 

Es funktioniert sehr gut und das Ergebnis kam bei 40 secs aber das Hinzufügen einer Extra Zustand wie AND C.city_id='4' erfordert eine zusätzliche Minute oder mehr; Dies ist immer noch akzeptabel, aber nicht bevorzugt.

Mein wirkliches Problem tritt auf, wenn ich versuche, eine andere Bedingung hinzuzufügen, um nur Duplikate von Firmen zu finden, die eine bestimmte Zeichenfolge im Namen haben, unter Verwendung dieser Bedingung AND C.name LIKE '%International%', dies gibt nur keine Ergebnisse zurück.

Kann mir jemand helfen herauszufinden, was ich falsch mache?

Dank

+0

Leider, ich glaube nicht, dass Sie eine effiziente Verwendung von Indizes in diesem Szenario machen - obwohl 1 Minute + scheint sehr langsam. – Strawberry

Antwort

6

Weil Sie auf dem Ergebnis einer Funktion anschließen, die Abfrage keinen Index verwenden können. Außerdem sind die Kosten für die Ausführung der REPLACE() auf allen Zeilen wahrscheinlich nicht vernachlässigbar.

Ich schlage vor, Sie zuerst eine indexierte Spalte hinzufügen, die die „abgespeckte“ Version der Saiten empfängt, und dann auf dieser Spalte die Abfrage mit einem Join auszuführen:

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, '.', ''), ',', '') ; 

Laufen die UPDATE könnte nehmen während das erste Mal, aber Sie könnten auch eine ON UPDATE und eine ON INSERT Trigger auf company, so dass stripped_name wird gefüllt und aktualisiert on-the-fly.

+0

Das ist eine großartige Idee - und offensichtlich (obwohl ich nicht daran gedacht habe!) – Strawberry

+0

Diese Lösung erhöht wirklich die Leistung, aber ich kann immer noch nicht das Ergebnis erhalten, wenn Sie nach einer bestimmten Zeichenfolge im Namen des Unternehmens suchen 'AND E.stripped_name LIKE '% International%'. Warum könnte es sein? – gustyaquino

+1

@gustyaquino Sind Sie sicher, dass es eine passende Zeile gibt? Möglicherweise verwenden Sie auch eine Sortierung, bei der die Groß-/Kleinschreibung beachtet wird. Bitte zeigen Sie uns die vollständige Struktur Ihrer Tabelle ('SHOW CREATE TABLE Firma;') – RandomSeed

0

Versuchen aus der tmp-Tabelle beginnen, da foreach Zeile in Unternehmen wird eine tmp Tabelle erstellt werden:

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, '.', ''), ',', '')