Die meisten SQL-Dialekte akzeptieren beide folgenden Abfragen:
SELECT a.foo, b.foo
FROM a, b
WHERE a.x = b.x
SELECT a.foo, b.foo
FROM a
LEFT JOIN b ON a.x = b.x
Wenn Sie nun einen Outer Join benötigen, ist natürlich die zweite Syntax erforderlich. Aber warum sollte ich bei einem inneren Join die zweite Syntax der ersten vorziehen (oder umgekehrt)?
Antworten:
Die alte Syntax, bei der nur die Tabellen
WHERE
aufgelistet und die Verknüpfungskriterien mithilfe der Klausel angegeben werden, ist in den meisten modernen Datenbanken veraltet.Es ist nicht nur für die Show gedacht, die alte Syntax kann mehrdeutig sein, wenn Sie sowohl INNER- als auch OUTER-Joins in derselben Abfrage verwenden.
Lassen Sie mich Ihnen ein Beispiel geben.
Angenommen, Sie haben 3 Tabellen in Ihrem System:
Jede Tabelle enthält zahlreiche miteinander verknüpfte Zeilen. Sie haben mehrere Unternehmen, und jedes Unternehmen kann mehrere Abteilungen haben, und jede Abteilung kann mehrere Mitarbeiter haben.
Ok, jetzt möchten Sie Folgendes tun:
Also machst du das:
Beachten Sie, dass der letzte eine innere Verknüpfung ist, um die Kriterien zu erfüllen, nach denen Sie nur Abteilungen mit Personen wünschen.
Ok, was passiert jetzt? Das Problem ist, dass es vom Datenbankmodul, dem Abfrageoptimierer, den Indizes und den Tabellenstatistiken abhängt. Lassen Sie mich erklären.
Wenn der Abfrageoptimierer feststellt, dass der Weg dazu darin besteht, zuerst ein Unternehmen zu übernehmen, dann die Abteilungen zu finden und dann eine innere Verbindung mit den Mitarbeitern herzustellen, erhalten Sie keine Unternehmen, die keine Abteilungen haben.
Der Grund dafür ist, dass die
WHERE
Klausel bestimmt, welche Zeilen im Endergebnis landen, nicht einzelne Teile der Zeilen.In diesem Fall ist die Spalte Department.ID aufgrund des linken Joins NULL. Wenn es also um INNER JOIN to Employee geht, gibt es keine Möglichkeit, diese Einschränkung für die Employee-Zeile zu erfüllen, und dies wird auch nicht der Fall sein erscheinen.
Wenn sich das Abfrageoptimierungsprogramm dagegen entscheidet, zuerst den Join von Abteilungsmitarbeitern in Angriff zu nehmen und dann einen Link-Join mit den Unternehmen durchzuführen, werden diese angezeigt.
Die alte Syntax ist also nicht eindeutig. Es gibt keine Möglichkeit, anzugeben, was Sie möchten, ohne sich mit Abfragehinweisen zu befassen, und einige Datenbanken haben überhaupt keine Möglichkeit.
Geben Sie die neue Syntax ein, mit der Sie auswählen können.
Wenn Sie beispielsweise alle Unternehmen möchten, wie in der Problembeschreibung angegeben, würden Sie Folgendes schreiben:
Hier geben Sie an, dass der Join von Abteilungsmitarbeitern als ein Join ausgeführt werden soll, und verbinden dann die Ergebnisse mit den Unternehmen.
Angenommen, Sie möchten nur Abteilungen, deren Name den Buchstaben X enthält. Auch hier besteht bei Joins im alten Stil die Gefahr, dass Sie das Unternehmen verlieren. Wenn es keine Abteilungen mit einem X im Namen hat, aber mit der neuen Syntax können Sie dies tun:
Diese zusätzliche Klausel wird für die Verknüpfung verwendet, ist jedoch kein Filter für die gesamte Zeile. Die Zeile wird möglicherweise mit Unternehmensinformationen angezeigt, enthält jedoch möglicherweise NULL-Werte in allen Abteilungs- und Mitarbeiterspalten für diese Zeile, da für diese Firma keine Abteilung mit einem X im Namen vorhanden ist. Dies ist mit der alten Syntax schwierig.
Aus diesem Grund hat Microsoft unter anderen Anbietern die alte äußere Join-Syntax, jedoch nicht die alte innere Join-Syntax seit SQL Server 2005 und höher abgelehnt. Die einzige Möglichkeit, mit einer Datenbank zu kommunizieren, die unter Microsoft SQL Server 2005 oder 2008 unter Verwendung der Outer Join-Syntax im alten Stil ausgeführt wird, besteht darin, diese Datenbank in den 8.0-Kompatibilitätsmodus (auch bekannt als SQL Server 2000) zu versetzen.
Darüber hinaus war die alte Methode, eine Reihe von Tabellen mit einer Reihe von WHERE-Klauseln auf den Abfrageoptimierer zu werfen, vergleichbar mit der Aussage "Hier sind Sie, tun Sie das Beste, was Sie können". Mit der neuen Syntax muss der Abfrageoptimierer weniger arbeiten, um herauszufinden, welche Teile zusammenpassen.
Da haben Sie es also.
LEFT and INNER JOIN ist die Welle der Zukunft.
quelle
OUTER JOIN
Syntax*=
/=*
/*=*
ist veraltet.Die JOIN-Syntax hält die Bedingungen in der Nähe der Tabelle, auf die sie angewendet werden. Dies ist besonders nützlich, wenn Sie eine große Anzahl von Tabellen verbinden.
Übrigens können Sie auch mit der ersten Syntax einen Outer Join ausführen:
Oder
Oder
quelle
Der erste Weg ist der ältere Standard. Die zweite Methode wurde in SQL-92, http://en.wikipedia.org/wiki/SQL, eingeführt . Der vollständige Standard kann unter http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt eingesehen werden .
Es dauerte viele Jahre, bis Datenbankunternehmen den SQL-92-Standard übernahmen.
Der Grund, warum die zweite Methode bevorzugt wird, ist der SQL-Standard gemäß dem ANSI- und ISO-Standardkomitee.
quelle
,
ist immer noch Standard.on
musste nurouter join
einmal eingeführt werden, sobald auch Unterauswahlen eingeführt wurden.Wenn Ihre FROM-Klausel Tabellen wie folgt auflistet:
Das Ergebnis ist ein Kreuzprodukt aller Zeilen in den Tabellen A, B, C. Dann wenden Sie die Einschränkung an,
WHERE tableA.id = tableB.a_id
die eine große Anzahl von Zeilen wegwirft, und dann weiter ...AND tableB.id = tableC.b_id
und Sie sollten dann nur die Zeilen erhalten, die Sie wirklich interessieren im.DBMS wissen, wie diese SQL so optimiert werden kann, dass der Leistungsunterschied zum Schreiben mit JOINs (falls vorhanden) vernachlässigbar ist. Unter Verwendung der Notation JOIN macht die SQL - Anweisung mehr lesbar (IMHO, nicht Joins schaltet die Anweisung in ein Chaos). Bei Verwendung des Cross-Produkts müssen Sie Join-Kriterien in der WHERE-Klausel angeben, und das ist das Problem mit der Notation. Sie überfüllen Ihre WHERE-Klausel mit Dingen wie
Dies wird nur verwendet, um das Kreuzprodukt einzuschränken. Die WHERE-Klausel sollte nur EINSCHRÄNKUNGEN für die Ergebnismenge enthalten. Wenn Sie Tabellenverknüpfungskriterien mit Ergebnismengeneinschränkungen mischen, ist es für Sie (und andere) schwieriger, Ihre Abfrage zu lesen. Sie sollten auf jeden Fall JOINs verwenden und die FROM-Klausel als FROM-Klausel und die WHERE-Klausel als WHERE-Klausel beibehalten.
quelle
Die zweite wird bevorzugt, da es weitaus weniger wahrscheinlich ist, dass eine versehentliche Querverbindung entsteht, wenn vergessen wird, die where-Klausel einzufügen. Ein Join mit no on-Klausel schlägt die Syntaxprüfung fehl, ein Join im alten Stil mit no where-Klausel schlägt nicht fehl und führt einen Cross-Join durch.
Wenn Sie später einen linken Join benötigen, ist es für die Wartung hilfreich, dass sich alle in derselben Struktur befinden. Und die alte Syntax ist seit 1992 veraltet. Es ist längst vorbei, sie nicht mehr zu verwenden.
Außerdem habe ich festgestellt, dass viele Leute, die ausschließlich die erste Syntax verwenden, Joins nicht wirklich verstehen und das Verständnis von Joins entscheidend ist, um bei Abfragen korrekte Ergebnisse zu erzielen.
quelle
Ich denke, es gibt einige gute Gründe auf dieser Seite, die zweite Methode zu verwenden - explizite JOINs. Der Clou ist jedoch, dass es viel einfacher wird, die verbleibenden Auswahlkriterien in der WHERE-Klausel zu sehen, wenn die JOIN-Kriterien aus der WHERE-Klausel entfernt werden.
In wirklich komplexen SELECT-Anweisungen wird es für einen Leser viel einfacher zu verstehen, was vor sich geht.
quelle
Die
SELECT * FROM table1, table2, ...
Syntax ist für einige Tabellen in Ordnung, wird jedoch exponentiell ( nicht unbedingt eine mathematisch genaue Aussage Anzahl von Tabellen ) immer schwieriger zu lesen.Die JOIN-Syntax ist (am Anfang) schwieriger zu schreiben, macht jedoch deutlich, welche Kriterien welche Tabellen beeinflussen. Dies macht es viel schwieriger, einen Fehler zu machen.
Wenn alle Joins INNER sind, sind beide Versionen gleichwertig. Sobald Sie jedoch irgendwo in der Anweisung einen OUTER-Join haben, werden die Dinge viel komplizierter und es ist praktisch garantiert, dass das, was Sie schreiben, nicht das abfragt, was Sie zu schreiben glauben.
quelle
Wenn Sie einen Outer Join benötigen, ist die zweite Syntax nicht immer erforderlich:
Orakel:
MSSQLServer (obwohl es in der Version 2000 veraltet ist ) / Sybase:
Aber zurück zu Ihrer Frage. Ich kenne die Antwort nicht, aber es hängt wahrscheinlich damit zusammen, dass ein Join natürlicher ist (zumindest syntaktisch) als das Hinzufügen eines Ausdrucks zu einer where- Klausel, wenn Sie genau das tun: Joining .
quelle
Ich höre viele Leute sich beschweren, dass der erste zu schwer zu verstehen ist und dass er unklar ist. Ich sehe kein Problem damit, aber nach dieser Diskussion verwende ich das zweite aus Gründen der Klarheit sogar für INNER JOINS.
quelle
Für die Datenbank sind sie am Ende gleich. Für Sie müssen Sie jedoch in einigen Situationen diese zweite Syntax verwenden. Um Abfragen zu bearbeiten, die letztendlich verwendet werden müssen (um herauszufinden, dass Sie eine linke Verknüpfung benötigen, bei der Sie eine gerade Verknüpfung hatten), und um die Konsistenz zu gewährleisten, würde ich nur die zweite Methode verwenden. Dies erleichtert das Lesen von Abfragen.
quelle
Nun, die erste und die zweite Abfrage können zu unterschiedlichen Ergebnissen führen, da ein LEFT JOIN alle Datensätze aus der ersten Tabelle enthält, auch wenn die richtige Tabelle keine entsprechenden Datensätze enthält.
quelle