Die Venn-Diagramme überzeugen mich nicht wirklich.
Sie zeigen keine Unterscheidung zwischen einem Cross Join und einem Inner Join, zum Beispiel, oder zeigen allgemein keine Unterscheidung zwischen verschiedenen Arten von Join-Prädikaten oder bieten einen Rahmen für das Nachdenken darüber, wie sie funktionieren werden.
Es gibt keinen Ersatz für das Verständnis der logischen Verarbeitung und es ist relativ einfach zu erfassen.
- Stellen Sie sich einen Cross Join vor.
- Werten Sie die
on
Klausel gegen alle Zeilen aus Schritt 1 aus, wobei die Prädikate ausgewertet werden müssen, die auf true
zutreffen
- (Für äußere Joins) fügen Sie alle äußeren Zeilen wieder in Schritt 2 ein, die verloren gegangen sind.
(Anmerkung: In der Praxis kann der Abfrageoptimierer effizientere Möglichkeiten finden, die Abfrage auszuführen, als die rein logische Beschreibung oben, aber das Endresultat muss dasselbe sein)
ICh beginne mit einer animierten Version eines Full Outer Join. Weitere Erklärungen folgen.
Erklärung
Quelltabelle/n
Beginnen Sie zunächst mit einem CROSS JOIN
(auch Kreuzprodukt genannt). Dies hat keine ON
Klausel und gibt einfach jede Kombination von Zeilen aus den beiden Tabellen zurück.
SELECT A.Colour, B.Colour FROM A CROSS JOIN B
Inner und äußere Joins haben ein "ON" Klausel-Prädikat.
- Inner Join. Bewertung der Bedingung in der "ON" Klausel für alle Zeilen im Ergebnis des Cross Joins. Wenn wahr, wird die verbundene Zeile zurückgegeben. Andernfalls wird sie verworfen.
- Left Outer Join. Das Gleiche wie beim Inner Join, dann werden für alle Zeilen in der linken Tabelle, die nicht übereinstimmen, NULL-Werte für die rechten Tabellenspalten ausgegeben.
- Right Outer Join. Das Gleiche wie beim Inner Join, dann werden für alle Zeilen in der rechten Tabelle, die nicht übereinstimmen, NULL-Werte für die linken Tabellenspalten ausgegeben.
- Full Outer Join. Das Gleiche wie beim Inner Join, dann werden links nicht übereinstimmende Zeilen wie beim Left Outer Join und rechts nicht übereinstimmende Zeilen wie beim Right Outer Join erhalten.
Einige Beispiele
SELECT A.Colour, B.Colour FROM A INNER JOIN B ON A.Colour = B.Colour
Das obige ist der klassische Gleichheitsjoin.
Animierte Version
SELECT A.Colour, B.Colour FROM A INNER JOIN B ON A.Colour NOT IN ('Green','Blue')
Die Inner Join-Bedingung muss nicht unbedingt eine Gleichheitsbedingung sein und sie muss nicht auf Spalten aus beiden (oder sogar einer) der Tabellen verweisen. Die Auswertung von A.Colour NOT IN ('Green','Blue')
in jeder Zeile des Cross Joins ergibt.
SELECT A.Colour, B.Colour FROM A INNER JOIN B ON 1 = 1
Die Join-Bedingung ergibt wahr für alle Zeilen im Ergebnis des Cross Joins, daher ist dies genau wie ein Cross Join. Ich werde das Bild der 16 Zeilen nicht wiederholen.
SELECT A.Colour, B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour
Äußere Joins werden logisch genauso wie Innere Joins ausgewertet, mit der Ausnahme, dass eine Zeile aus der linken Tabelle (bei einem Linken Join), die überhaupt nicht mit einer Zeile aus der rechten Tabelle übereinstimmt, im Ergebnis mit NULL
Werten für die Spalten der rechten Tabelle erhalten bleibt.
SELECT A.Colour, B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour IS NULL
Dies beschränkt das vorherige Ergebnis einfach darauf, nur die Zeilen zurückzugeben, bei denen B.Colour IS NULL
ist. In diesem Fall handelt es sich um die Zeilen, die erhalten wurden, da sie keine Übereinstimmung in der rechten Tabelle hatten, und die Abfrage gibt die einzelne rote Zeile zurück, die nicht mit der Tabelle B
übereinstimmte. Dies wird als Anti-Semi-Join bezeichnet.
Es ist wichtig, eine Spalte für den IS NULL
Test auszuwählen, die entweder nicht NULL-fähig ist oder für die die Join-Bedingung sicherstellt, dass alle NULL
Werte ausgeschlossen werden, um zu vermeiden, einfache zeilen zurückzubringen, die zufällig einen NULL
-Wert für diese Spalte haben in Zusatz zu den nicht übereinstimmenden Reihen.
SELECT A.Colour, B.Colour FROM A RIGHT OUTER JOIN B ON A.Colour = B.Colour
Rechte äußere Joins wirken ähnlich wie linke äußere Joins, mit der Ausnahme, dass sie nicht übereinstimmende Zeilen aus der rechten Tabelle bewahren und die linken Spalten mit NULL erweitern.
SELECT A.Colour, B.Colour FROM A FULL OUTER JOIN B ON A.Colour = B.Colour
Vollständige äußere Joins kombinieren das Verhalten von linken und rechten Joins und bewahren die nicht übereinstimmenden Zeilen aus beiden linken und rechten Tabellen.
SELECT A.Colour, B.Colour FROM A FULL OUTER JOIN B ON 1 = 0
Keine Zeilen im Cross Join entsprechen dem 1=0
Prädikat. Alle Zeilen auf beiden Seiten werden unter Verwendung der normalen äußeren Join-Regeln beibehalten, wobei in den Spalten der Tabelle auf der anderen Seite NULL verwendet wird.
SELECT COALESCE(A.Colour, B.Colour) AS Colour FROM A FULL OUTER JOIN B ON 1 = 0
Mit einer geringfügigen Änderung an der vorherigen Abfrage könnte man eine UNION ALL
der beiden Tabellen simulieren.
SELECT A.Colour, B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour WHERE B.Colour = 'Green'
Beachten Sie, dass die WHERE
Klausel (falls vorhanden) logisch nach dem Join ausgeführt wird. Ein häufiger Fehler besteht darin, einen linken äußeren Join durchzuführen und dann eine WHERE-Klausel mit einer Bedingung auf der rechten Tabelle einzuschließen, die letztendlich die nicht übereinstimmenden Zeilen ausschließt. Das obige führt den äußeren Join durch...
...Und dann wird die "Where" Klausel ausgeführt. NULL= 'Green'
ergibt nicht wahr, daher wird die durch den äußeren Join erhaltene Zeile verworfen (zusammen mit der blauen), wodurch der Join effektiv wieder in einen inneren umgewandelt wird.
Wenn die Absicht war, nur Zeilen aus B einzuschließen, bei denen die Farbe Grün ist und alle Zeilen aus A unabhängig davon, wäre die richtige Syntax:
SELECT A.Colour, B.Colour FROM A LEFT OUTER JOIN B ON A.Colour = B.Colour AND B.Colour = 'Green'
SQL Fiddle
Sehen Sie sich diese Beispiele live bei SQLFiddle.com.
87 Stimmen
Von den Antworten & Kommentaren & ihren Verweisen unten erklärt nur einer tatsächlich, wie Venn-Diagramme die Operatoren darstellen: Der Bereich der Kreisüberschneidung repräsentiert die Menge der Zeilen in A JOIN B. Der einzigartige Bereich jedes Kreises repräsentiert die Menge der Zeilen, die man erhält, indem man die Zeilen der Tabelle nimmt, die nicht an A JOIN B teilnehmen, und die Spalten hinzufügt, die einzigartig für die andere Tabelle sind, alle auf NULL gesetzt. (Und die meisten geben eine vage falsche Entsprechung der Kreise zu A und B.)
22 Stimmen
@DanteTheSmith Nein, das leidet unter denselben Problemen wie die Diagramme hier. Lesen Sie meinen Kommentar oben zur Frage und unten zu diesem Blog-Beitrag: "Jeff widerspricht seinem Blog ein paar Seiten weiter unten in den Kommentaren". Venn-Diagramme zeigen Elemente in Mengen. Versuchen Sie einfach genau zu identifizieren, was die Mengen sind und welche Elemente in diesen Diagrammen sind. Die Mengen sind nicht die Tabellen und die Elemente nicht ihre Zeilen. Außerdem können zwei Tabellen verbunden werden, sodass PKs & FKs irrelevant sind. Alles falsch. Sie tun genau das, was Tausende von anderen getan haben - haben einen ungefähren Eindruck, dass Sie (fälschlicherweise) annehmen, Sinn macht.
2 Stimmen
Mein vorheriger Kommentar bezieht sich auf einen verwirrten, abgelehnten Blog-Beitrag von Jeff Atwood.
2 Stimmen
Mein 1. Kommentarlink ist extern, aber i.stack.imgur.com hat dauerhafte Kopien seiner Illustrationen von Ausgabe (nicht Eingabe) für inner, left & full Joins (in Grün).