Ich habe eine Abfrage, die so aussieht:
SELECT *
FROM TBLA A
LEFT JOIN TBLB B ON A.Col1 = B.Col2
RIGHT JOIN TBLC C ON B.Col3 = C.Col4
JOIN TBLD D ON C.Col5 = D.Col6
In welcher Reihenfolge werden die Verknüpfungen aufgelöst? Ich interessiere mich am meisten für SQL Server und werde eine Erklärung dafür als Antwort markieren, interessiere mich aber auch für den ANSI / ISO-Standard und dessen Funktionsweise in den verschiedenen RDBMS.
Der Grund für diese Frage war herauszufinden, warum sich die Ergebnisse von dieser Abfrage unterschieden
SELECT *
FROM TBLA A
CROSS JOIN TBLC C
LEFT JOIN TBLB B ON A.Col1 = B.Col2 AND B.Col3 = C.Col4
JOIN TBLD D ON C.Col5 = D.Col6
LEFT
undRIGHT JOIN
in der gleichen Abfrage bittet um Verwirrung, IMHO.Antworten:
Logischerweise werden die Verknüpfungen in der Reihenfolge der
ON
Klauseln von links nach rechts aufgelöst.Die Ausgabe jedes Joins ist eine virtuelle Tabelle, die in den nächsten Join eingeht.
Für die Abfrage in Ihrer Frage wird dann das Ergebnis der virtuellen Tabelle von
A LJ B
direkt mit verbundenC
. Die Verknüpfungsbedingung vonB.Col3 = C.Col4
verliert alle erweiterten Nullzeilen, die durch die ursprüngliche linke Verknüpfung erhalten wurden, und verwandelt die erste Verknüpfung effektiv wieder in eine innere Verknüpfung. Die resultierende virtuelle Tabelle (von der alle Zeilen erhalten bleibenC
) wird dann mit der inneren Verknüpfung verknüpftD
.So kann Ihre anfängliche Abfrage als vereinfacht werden
Welches ist effektiv das gleiche wie
(A IJ B) ROJ (C IJ D)
Die Reihenfolge der
ON
Klauseln entspricht nicht unbedingt der Reihenfolge, in der die Tabellen in der Abfrage angezeigt werden. Dies könnte auch umgeschrieben werden als(C IJ D) LOJ (A IJ B)
Die Position der on-Klauseln bedeutet, dass der äußere Join zwischen den beiden virtuellen Tabellen ausgeführt wird, die aus
(C IJ D)
und(A IJ B)
nicht nur aus einer einzelnen Tabelle resultieren .In Ihrer zweiten konzeptionellen Abfrage wird die virtuelle Tabelle konzeptionell
A x C
mit B verknüpft, wobei das gesamte kartesische Produkt erhalten bleibt. Das Ergebnis wird dannD
mit dem Prädikat verknüpftC.Col5 = D.Col6
. Dies eliminiert alle Zeilen aus dem Endergebnis, die keine innere Verbindung zwischenC
undD
bedeuten, dass es äquivalent zu istquelle
(A IJ B) ROJ (C IJ D)
. Ich denke es ist((A IJ B) ROJ C) IJ D)
.In PostgreSQL:
http://www.postgresql.org/docs/9.1/static/sql-select.html#SQL-FROM
quelle