Nach dem Lesen handelt es sich nicht um ein Duplikat von Explicit vs Implicit SQL Joins . Die Antwort kann verwandt (oder sogar gleich) sein, aber die Frage ist anders.
Was ist der Unterschied und was sollte in jedem gehen?
Wenn ich die Theorie richtig verstehe, sollte das Abfrageoptimierungsprogramm beide austauschbar verwenden können.
Antworten:
Sie sind nicht dasselbe.
Betrachten Sie diese Fragen:
und
Der erste gibt eine Bestellung und gegebenenfalls deren Zeilen für die Bestellnummer zurück
12345
. Die zweite Option gibt alle Bestellungen zurück, aber nur der Bestellung12345
sind Zeilen zugeordnet.Mit einem
INNER JOIN
sind die Klauseln effektiv gleichwertig. Nur weil sie funktional gleich sind, weil sie die gleichen Ergebnisse liefern, heißt das nicht, dass die beiden Arten von Klauseln die gleiche semantische Bedeutung haben.quelle
Angelegenheiten für äußere Verbindungen
ein.
WHERE
Klausel: Nachher Beitritt. Datensätze werden nach dem Beitritt gefiltert.b.
ON
Klausel - Vor dem Beitritt. Datensätze (aus der rechten Tabelle) werden vor dem Beitritt gefiltert. Dies kann im Ergebnis als null enden (seit OUTER-Join).Beispiel : Betrachten Sie die folgenden Tabellen:
a) Inside-
WHERE
Klausel:b) Inside-
JOIN
Klauselquelle
intermediate join table
? Ein 'Erklären'-Befehl?Auf
INNER JOIN
s sind sie austauschbar, und der Optimierer ordnet sie nach Belieben neu an.Auf
OUTER JOIN
s sind sie nicht unbedingt austauschbar, abhängig davon, von welcher Seite der Verknüpfung sie abhängen.Ich habe sie je nach Lesbarkeit an beiden Stellen platziert.
quelle
Orders.Join( OrderLines, x => x.ID, x => OrderID, (o,l) => new {Orders = o, Lines = l}).Where( ol => ol.Orders.ID = 12345)
Ich mache es so:
Fügen Sie die Join-Bedingungen immer in die
ON
Klausel ein, wenn Sie eineINNER JOIN
. Fügen Sie der ON-Klausel also keine WHERE-Bedingungen hinzu, sondern fügen Sie sie in dieWHERE
Klausel ein.Wenn Sie a ausführen
LEFT JOIN
, fügen Sie derON
Klausel für die Tabelle rechts alle WHERE-Bedingungen hinzu Seite des Joins . Dies ist ein Muss, da durch Hinzufügen einer WHERE-Klausel, die auf die rechte Seite des Joins verweist, der Join in einen INNER JOIN konvertiert wird.Die Ausnahme ist, wenn Sie nach Datensätzen suchen, die sich nicht in einer bestimmten Tabelle befinden. Sie würden den Verweis auf einen eindeutigen Bezeichner (der niemals NULL ist) in der Tabelle RIGHT JOIN zur WHERE-Klausel auf folgende Weise hinzufügen :
WHERE t2.idfield IS NULL
. Sie sollten also nur auf eine Tabelle auf der rechten Seite des Joins verweisen, um die Datensätze zu finden, die nicht in der Tabelle enthalten sind.quelle
Bei einer inneren Verbindung bedeuten sie dasselbe. Je nachdem, ob Sie die Join-Bedingung in die WHERE-Klausel oder die ON-Klausel einfügen, erhalten Sie jedoch unterschiedliche Ergebnisse in einem Outer-Join. Schauen Sie sich diese verwandte Frage und diese Antwort (von mir) an.
Ich denke, es ist am sinnvollsten, die Join-Bedingung immer in die ON-Klausel aufzunehmen (es sei denn, es handelt sich um eine äußere Verknüpfung, und Sie möchten sie tatsächlich in der where-Klausel haben), da dies für jeden, der Ihre Abfrage liest, klarer wird Unter welchen Bedingungen werden die Tabellen verknüpft, und es wird auch verhindert, dass die WHERE-Klausel Dutzende von Zeilen lang ist.
quelle
Tabellenbeziehung
In Anbetracht dessen haben wir Folgendes
post
undpost_comment
Tabellen:Das
post
hat folgende Aufzeichnungen:und das
post_comment
hat die folgenden drei Zeilen:SQL INNER JOIN
Mit der SQL JOIN-Klausel können Sie Zeilen zuordnen, die zu verschiedenen Tabellen gehören. Ein CROSS JOIN erstellt beispielsweise ein kartesisches Produkt, das alle möglichen Kombinationen von Zeilen zwischen den beiden Verknüpfungstabellen enthält.
Während CROSS JOIN in bestimmten Szenarien nützlich ist, möchten Sie meistens Tabellen basierend auf einer bestimmten Bedingung verknüpfen. Und hier kommt INNER JOIN ins Spiel.
Mit SQL INNER JOIN können wir das kartesische Produkt des Verbindens zweier Tabellen basierend auf einer Bedingung filtern, die über die ON-Klausel angegeben wird.
SQL INNER JOIN - ON "immer wahr" Bedingung
Wenn Sie eine "immer wahre" Bedingung angeben, filtert INNER JOIN die verknüpften Datensätze nicht und die Ergebnismenge enthält das kartesische Produkt der beiden Verknüpfungstabellen.
Zum Beispiel, wenn wir die folgende SQL INNER JOIN-Abfrage ausführen:
Wir erhalten alle Kombinationen
post
undpost_comment
Aufzeichnungen:Wenn die Bedingung der ON-Klausel "immer wahr" ist, entspricht INNER JOIN einfach einer CROSS JOIN-Abfrage:
SQL INNER JOIN - ON "immer falsch" Bedingung
Wenn andererseits die ON-Klauselbedingung "immer falsch" ist, werden alle verknüpften Datensätze herausgefiltert und die Ergebnismenge ist leer.
Wenn wir also die folgende SQL INNER JOIN-Abfrage ausführen:
Wir werden kein Ergebnis zurückbekommen:
Dies liegt daran, dass die obige Abfrage der folgenden CROSS JOIN-Abfrage entspricht:
SQL INNER JOIN - ON-Klausel unter Verwendung der Spalten Fremdschlüssel und Primärschlüssel
Die häufigste ON-Klauselbedingung ist diejenige, die die Fremdschlüsselspalte in der untergeordneten Tabelle mit der Primärschlüsselspalte in der übergeordneten Tabelle übereinstimmt, wie in der folgenden Abfrage dargestellt:
Bei der Ausführung der obigen SQL INNER JOIN-Abfrage erhalten wir die folgende Ergebnismenge:
Daher werden nur die Datensätze, die der ON-Klauselbedingung entsprechen, in die Abfrageergebnismenge aufgenommen. In unserem Fall enthält die Ergebnismenge alle
post
zusammen mit ihrenpost_comment
Datensätzen. Die nicht zugeordnetenpost
Zeilenpost_comment
werden ausgeschlossen, da sie die ON-Klauselbedingung nicht erfüllen können.Auch hier entspricht die obige SQL INNER JOIN-Abfrage der folgenden CROSS JOIN-Abfrage:
Die nicht angeschlagenen Zeilen erfüllen die WHERE-Klausel, und nur diese Datensätze werden in die Ergebnismenge aufgenommen. Auf diese Weise können Sie am besten visualisieren, wie die INNER JOIN-Klausel funktioniert.
Fazit
Eine INNER JOIN-Anweisung kann als CROSS JOIN mit einer WHERE-Klausel umgeschrieben werden, die der gleichen Bedingung entspricht, die Sie in der ON-Klausel der INNER JOIN-Abfrage verwendet haben.
quelle
Es gibt einen großen Unterschied zwischen der where-Klausel und der on-Klausel , wenn es um Left Join geht.
Hier ist ein Beispiel:
Dort ist fid die ID von Tabelle t2.
Abfrage zu "on-Klausel":
Abfrage zu "where-Klausel":
Es ist klar, dass die erste Abfrage einen Datensatz von t1 und seine abhängige Zeile von t2, falls vorhanden, für Zeile t1.v = 'K' zurückgibt.
Die zweite Abfrage gibt Zeilen von t1 zurück, aber nur für t1.v = 'K' ist eine Zeile zugeordnet.
quelle
In Bezug auf das Optimierungsprogramm sollte es keinen Unterschied machen, ob Sie Ihre Join-Klauseln mit ON oder WHERE definieren.
Ich denke jedoch, es ist viel klarer, die ON-Klausel zu verwenden, wenn Joins ausgeführt werden. Auf diese Weise haben Sie einen bestimmten Abschnitt Ihrer Abfrage, der vorschreibt, wie der Join behandelt wird, anstatt ihn mit den übrigen WHERE-Klauseln zu vermischen.
quelle
Betrachten wir diese Tabellen:
EIN
B.
id_A
ein Fremdschlüssel zu Tisch seinA
Schreiben dieser Abfrage:
Wird dieses Ergebnis liefern:
Was in A, aber nicht in B ist, bedeutet, dass es für B Nullwerte gibt.
Betrachten wir nun einen bestimmten Teil in
B.id_A
und heben Sie ihn aus dem vorherigen Ergebnis hervor:Schreiben dieser Abfrage:
Wird dieses Ergebnis liefern:
Weil dies im inneren Join die Werte entfernt, die nicht in sind
B.id_A = SpecificPart
Ändern wir nun die Abfrage wie folgt:
Das Ergebnis ist jetzt:
Da das gesamte Ergebnis gegen das
B.id_A = SpecificPart
Entfernen der Teile gefiltert wirdB.id_A = NULL
, die sich in A befinden und nicht in B.quelle
Versuchen Sie, Daten zu verbinden oder Daten zu filtern?
Aus Gründen der Lesbarkeit ist es am sinnvollsten, diese Anwendungsfälle auf ON bzw. WHERE zu isolieren.
Es kann sehr schwierig werden, eine Abfrage zu lesen, bei der die JOIN-Bedingung und eine Filterbedingung in der WHERE-Klausel vorhanden sind.
In Bezug auf die Leistung sollten Sie keinen Unterschied feststellen, obwohl verschiedene SQL-Typen die Abfrageplanung manchmal unterschiedlich handhaben, sodass es sich lohnen kann, sie auszuprobieren
¯\_(ツ)_/¯
( beachten Sie, dass das Caching die Abfragegeschwindigkeit beeinflusst).Wie andere bereits bemerkt haben, erhalten Sie bei Verwendung eines äußeren Joins unterschiedliche Ergebnisse, wenn Sie die Filterbedingung in die ON-Klausel einfügen, da sie nur eine der Tabellen betrifft.
Ich habe hier einen ausführlicheren Beitrag dazu geschrieben: https://dataschool.com/learn/difference-between-where-and-on-in-sql
quelle
In SQL sind die Klauseln 'WHERE' und 'ON' bedingte Statemants. Der Hauptunterschied zwischen ihnen besteht jedoch darin, dass die Klausel 'Where' in Select / Update-Anweisungen zum Angeben der Bedingungen verwendet wird, während die Klausel 'ON' verwendet wird wird in Verknüpfungen verwendet, wo überprüft oder überprüft wird, ob die Datensätze in den Ziel- und Quelltabellen übereinstimmen, bevor die Tabellen verknüpft werden
Zum Beispiel: - 'WO'
Zum Beispiel: - 'ON'
Es gibt zwei Tabellen employee und employee_details, die übereinstimmenden Spalten sind employee_id.
Hoffe ich habe deine Frage beantwortet. Für Klarstellungen zurücksetzen.
quelle
WHERE
anstelle von verwendenON
, nicht wahr? sqlfiddle.com/#!2/ae5b0/14/0Ich denke, es ist der Join-Sequenz-Effekt. Im Fall der Verknüpfung oben links führt SQL zuerst die Verknüpfung nach links und dann den Filter where where aus. Suchen Sie im Downer-Fall zuerst Orders.ID = 12345 und schließen Sie sich dann an.
quelle
Für eine innere Verbindung
WHERE
undON
kann austauschbar verwendet werden. Tatsächlich ist es möglich,ON
in einer korrelierten Unterabfrage zu verwenden. Zum Beispiel:Dies ist (IMHO) für einen Menschen äußerst verwirrend und es ist sehr leicht zu vergessen,
table1
auf irgendetwas zu verlinken (da die "Treiber" -Tabelle keine "Ein" -Klausel enthält), aber es ist legal.quelle
Für eine bessere Leistung sollten Tabellen eine spezielle indizierte Spalte haben, die für JOINS verwendet werden kann.
Wenn also die Spalte, für die Sie eine Bedingung festlegen, keine dieser indizierten Spalten ist, ist es meiner Meinung nach besser, sie in WHERE zu belassen.
Sie verbinden sich also mit den indizierten Spalten und führen nach JOIN die Bedingung für die nicht indizierte Spalte aus.
quelle
Normalerweise wird die Filterung in der WHERE-Klausel verarbeitet, sobald die beiden Tabellen bereits verbunden wurden. Es ist jedoch möglich, dass Sie eine oder beide Tabellen filtern möchten, bevor Sie sie verbinden. Das heißt, die where-Klausel gilt für die gesamte Ergebnismenge, während die on-Klausel nur für den betreffenden Join gilt.
quelle
Ich denke, diese Unterscheidung kann am besten durch die logische Reihenfolge der Operationen in SQL erklärt werden , die vereinfacht ist:
FROM
(einschließlich Joins)WHERE
GROUP BY
HAVING
WINDOW
SELECT
DISTINCT
UNION
,INTERSECT
,EXCEPT
ORDER BY
OFFSET
FETCH
Joins sind keine Klausel der select-Anweisung, sondern ein Operator innerhalb von
FROM
. Als solche sind alleON
Klauseln, die zum entsprechendenJOIN
Operator gehören, logisch "bereits passiert" , wenn die logische Verarbeitung dieWHERE
Klausel erreicht. Dies bedeutet, dass im Fall vonLEFT JOIN
beispielsweise die Semantik des äußeren Joins bereits zum Zeitpunkt desWHERE
Anwendung Klausel ist.Ich habe das folgende Beispiel in diesem Blog-Beitrag ausführlicher erläutert . Beim Ausführen dieser Abfrage:
Das
LEFT JOIN
hat keinen wirklich nützlichen Effekt, denn selbst wenn ein Schauspieler nicht in einem Film gespielt hat, wird der Schauspieler so gefiltert, wie es seinFILM_ID
wird,NULL
und dieWHERE
Klausel filtert eine solche Zeile. Das Ergebnis ist so etwas wie:Das heißt, als ob wir uns innerlich den beiden Tischen angeschlossen hätten. Wenn wir das Filterprädikat in der
ON
Klausel verschieben, wird es jetzt zu einem Kriterium für die äußere Verknüpfung:Das heißt, das Ergebnis enthält Schauspieler ohne Filme oder ohne Filme mit
FILM_ID < 10
Zusamenfassend
Platzieren Sie Ihr Prädikat logischerweise immer dort, wo es am sinnvollsten ist.
quelle
Was Ihre Frage betrifft,
Es ist dasselbe 'on' oder 'where' bei einem inneren Join, solange Ihr Server es bekommen kann:
und
Die Option "Wo", die nicht alle Dolmetscher kennen, sollte möglicherweise vermieden werden. Und natürlich ist die Ein-Klausel klarer.
quelle
Das ist meine Lösung.
Sie müssen die
GROUP BY
es zur Arbeit kommen.Ich hoffe das hilft.
quelle