webentwicklung-frage-antwort-db.com.de

Wie verwende ich ein Like mit einem Join in SQL?

Ich habe 2 Tabellen, sagen wir Tabelle A und Tabelle B, und ich möchte einen Join ausführen, aber die Übereinstimmungsbedingung muss sein, dass eine Spalte von A einer Spalte von B gleicht, was bedeutet, dass alles vor oder nach der Spalte in kommen kann B:

zum Beispiel: wenn die Spalte in A 'foo' ist. Dann würde der Join passen, wenn die Spalte in B entweder 'fooblah', 'somethingfooblah' oder nur 'foo' lautet. Ich kann die Platzhalter in einer Standardanweisung verwenden, bin aber verwirrt, wenn ich einen Join mache. Macht das Sinn? Vielen Dank.

44
jim

Mit INSTR :

SELECT *
  FROM TABLE a
  JOIN TABLE b ON INSTR(b.column, a.column) > 0

Verwendung von LIKE:

SELECT *
  FROM TABLE a
  JOIN TABLE b ON b.column LIKE '%'+ a.column +'%'

Verwenden von LIKE mit CONCAT:

SELECT *
  FROM TABLE a
  JOIN TABLE b ON b.column LIKE CONCAT('%', a.column ,'%')

Beachten Sie, dass Sie in allen Optionen die Spaltenwerte wahrscheinlich VOR dem Vergleich in Großbuchstaben setzen möchten, um sicherzustellen, dass Übereinstimmungen ohne Berücksichtigung der Groß- und Kleinschreibung angezeigt werden:

SELECT *
  FROM (SELECT UPPER(a.column) 'ua'
         TABLE a) a
  JOIN (SELECT UPPER(b.column) 'ub'
         TABLE b) b ON INSTR(b.ub, a.ua) > 0

Die effizienteste hängt letztendlich von der Ausgabe EXPLAIN-Plan ab.

JOIN -Klauseln sind identisch mit dem Schreiben von WHERE -Klauseln. Die Syntax JOIN wird auch als ANSI JOINs bezeichnet, da sie standardisiert wurden. Nicht-ANSI-JOINs sehen folgendermaßen aus:

SELECT *
  FROM TABLE a,
       TABLE b
 WHERE INSTR(b.column, a.column) > 0

Ich werde mich nicht mit einem Non-ANSI LEFT JOIN-Beispiel beschäftigen. Der Vorteil der ANSI JOIN-Syntax besteht darin, dass das, was Tabellen miteinander verbindet, von dem, was in der WHERE -Klausel tatsächlich geschieht, getrennt wird.

75
OMG Ponies

In MySQL könnten Sie versuchen:

SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');

Dies wäre natürlich eine äußerst ineffiziente Abfrage, da ein vollständiger Tabellenscan durchgeführt würde.

Update: Hier ist ein Beweis


create table A (MYCOL varchar(255));
create table B (MYCOL varchar(255));
insert into A (MYCOL) values ('foo'), ('bar'), ('baz');
insert into B (MYCOL) values ('fooblah'), ('somethingfooblah'), ('foo');
insert into B (MYCOL) values ('barblah'), ('somethingbarblah'), ('bar');
SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');
+-------+------------------+
| MYCOL | MYCOL            |
+-------+------------------+
| foo   | fooblah          |
| foo   | somethingfooblah |
| foo   | foo              |
| bar   | barblah          |
| bar   | somethingbarblah |
| bar   | bar              |
+-------+------------------+
6 rows in set (0.38 sec)
19
Asaph

Wenn Sie dies häufig tun müssen, können Sie die Beziehung zwischen den Tabellen A und B denormalisieren.

Beispielsweise könnten Sie beim Einfügen in Tabelle B null oder mehr Einträge in eine Verknüpfungstabellenzuordnung schreiben, die auf einer partiellen Zuordnung basiert. In ähnlicher Weise können Änderungen an einer der Tabellen diese Zuordnung aktualisieren.

Dies hängt alles davon ab, wie oft die Tabellen A und B geändert werden. Wenn sie ziemlich statisch sind, ist es weniger schmerzhaft, einen Treffer auf INSERT zu erzielen als wiederholte Treffer auf SELECT.

5
David Andres

Die Verwendung bedingter Kriterien in einem Join unterscheidet sich definitiv von der Where-Klausel. Die Kardinalität zwischen den Tabellen kann zu Unterschieden zwischen Joins- und Where-Klauseln führen.

Wenn Sie beispielsweise eine Like-Bedingung in einem Outer Join verwenden, werden alle Datensätze in der ersten im Join aufgelisteten Tabelle beibehalten. Wenn Sie dieselbe Bedingung in der Where-Klausel verwenden, wird der Join implizit in einen Inner-Join geändert. Der Datensatz muss im Allgemeinen in beiden Tabellen vorhanden sein, um den bedingten Vergleich in der Where-Klausel durchzuführen.

Im Allgemeinen verwende ich den in einer der vorherigen Antworten angegebenen Stil.

tbl_A as ta
    LEFT OUTER JOIN tbl_B AS tb
            ON ta.[Desc] LIKE '%' + tb.[Desc] + '%'

Auf diese Weise kann ich den Verbindungstyp steuern.

2
Geoffrey Fuller

Wenn das Schreiben von Abfragen mit unserem Server LIKE oder INSTR (oder CHARINDEX in T-SQL) zu lange dauert, verwenden wir LEFT wie in der folgenden Struktur:

select *
from little
left join big
on left( big.key, len(little.key) ) = little.key

Ich verstehe, dass dies möglicherweise nur mit variierenden Endungen für die Abfrage funktioniert, im Gegensatz zu anderen Vorschlägen mit '%' + b + '%', aber es ist ausreichend und viel schneller, wenn Sie nur b + '%' benötigen.

Eine andere Möglichkeit zur Optimierung der Geschwindigkeit (aber nicht des Speichers) besteht darin, in "little" eine Spalte zu erstellen, die "len (little.key)" als "lenkey" und in der obigen Abfrage "user that" ist.