Ich erhalte unterschiedliche Ergebnisse basierend auf einer Filterbedingung in einer Abfrage basierend auf dem Ort, an dem ich die Filterbedingung anlege. Meine Fragen sind:
Angesichts des vereinfachten Szenarios:
%Vor%Ich ging davon aus, dass die Abfragen die gleichen Resultsets zurückgeben würden, und ich war überrascht, wenn dies nicht der Fall war. Ich benutze MS SQL2005 und in den tatsächlichen Abfragen, Abfrage 1 zurückgegeben ~ 700 Zeilen und Abfrage 2 zurückgegeben ~ 1100 Zeilen und ich konnte kein Muster erkennen, auf dem Zeilen zurückgegeben wurden und welche Zeilen ausgeschlossen wurden. In Abfrage 1 gab es noch viele Zeilen mit untergeordneten Zeilen mit Daten und NULL-Daten. Ich bevorzuge den Stil von Abfrage 2 (und ich denke, es ist optimaler), aber ich dachte, die Abfragen würden die gleichen Ergebnisse zurückgeben.
Bearbeiten / Zusammenfassung:
Hier wurden einige großartige Antworten gegeben. Es fiel mir schwer zu entscheiden, wem ich die Antwort geben sollte. Ich entschied mich, mit mdma zu gehen, da es die erste Antwort und eine der klarsten war. Basierend auf den gelieferten Antworten, hier ist meine Zusammenfassung:
Mögliche Ergebnisse:
Abfrageergebnisse:
Abfrage 2 gibt wegen des linken Joins immer ein übergeordnetes Element zurück. In Abfrage 1 wird die WHERE-Klausel nach dem linken Join ausgeführt, sodass Eltern mit Kindern ausgeschlossen werden, bei denen keine der untergeordneten Elemente dem Filter entspricht (Fall B1).
Hinweis: Nur Elterninformationen werden in Fall B1 zurückgegeben, und in Fall B2 werden nur die Eltern- / Kindinformationen zurückgegeben, die mit dem Filter übereinstimmen.
HLGEM hat einen guten Link zur Verfügung gestellt:
Die erste Abfrage gibt Fälle zurück, in denen der Elternteil keine Kinder hat oder wo einige Kinder die Filterbedingung erfüllen. Insbesondere Fälle, in denen der Elternteil ein Kind hat, aber nicht mit der Filterbedingung übereinstimmt, werden weggelassen.
Die zweite Abfrage gibt eine Zeile für alle Eltern zurück. Wenn die Filterbedingung nicht übereinstimmt, wird für alle Spalten von c ein NULL-Wert zurückgegeben. Aus diesem Grund erhalten Sie in Abfrage 2 mehr Zeilen - Eltern mit Kindern, die nicht mit der Filterbedingung übereinstimmen, werden mit NULL-Kindwerten ausgegeben, wobei in der ersten Abfrage diese herausgefiltert werden.
Ja, es gibt einen großen Unterschied. Wenn Sie Filter in der ON-Klausel auf einem LINKEN JOIN platzieren, wird der Filter angewendet, bevor die Ergebnisse mit der äußeren Tabelle verknüpft werden. Wenn Sie einen Filter in der WHERE-Klausel anwenden, geschieht dies, nachdem der LEFT JOIN angewendet wurde.
Kurz gesagt, die erste Abfrage schließt Zeilen mit untergeordneten Zeilen aus, aber die untergeordnete Beschreibung entspricht nicht der Filterbedingung, während die zweite Abfrage immer eine Zeile für das übergeordnete Element zurückgibt.
Für dieses Recordset:
%Vor%, die erste Abfrage würde 0
records zurückgeben, während die zweite Abfrage 1
record:
Jetzt WHERE
-Klausel hinzufügen:
WHERE
-Klausel filtert die Datensätze, die im vorherigen Schritt zurückgegeben wurden, und kein Datensatz entspricht der Bedingung.
Während dieser:
%Vor%gibt einen einzelnen falschen Datensatz zurück.
Die Eltern, die nur Kinder mit description != 'FilterCondition'
haben, werden in Abfrage 1 nicht angezeigt, da die WHERE-Klausel nach dem Verbinden der Zeilen ausgewertet wird.
Die erste Abfrage gibt weniger Zeilen zurück, da nur Zeilen zurückgegeben werden, die keine untergeordneten Elemente haben oder untergeordnete Elemente haben, die der Filterbedingung entsprechen.
Die WHERE-Klausel schließt den Rest aus (diejenigen, die untergeordnete Elemente haben, aber nicht mit der Filterbedingung übereinstimmen).
Die zweite Abfrage zeigt alle drei obigen Bedingungen.
Ich bemerke einige Unterschiede, die die Ergebnisse variieren können. In der ersten Abfrage haben Sie LEFT OUTER JOIN Child c ON (p.ID = c.ParentID)
und dann in der zweiten Abfrage LEFT OUTER JOIN Child c
ON (p.ID = c.ParentID AND c.Description = 'FilterCondition')
und dies bewirkt, dass die zweite Abfrage alle Eltern mit Kindern zurückgibt, die Ihre Bedingung erfüllen wo als erste Bedingung auch die Eltern wit keine Kinder zurückgeben werden. Sehen Sie sich auch den Vorrang von Join-Bedingungen und Bedingungen an.