Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

WHERE-Klausel vs. ON bei Verwendung von JOIN

Achten Sie nur auf den Unterschied zu äußeren Verknüpfungen. Eine Abfrage, bei der ein Filter von b.IsApproved verwendet wird (auf dem rechten Tisch, Bar) wird zum ON hinzugefügt Bedingung des JOIN :

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId); 

Ist NICHT dasselbe wie das Platzieren des Filters im WHERE Klausel:

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1); 

Da für 'fehlgeschlagene' Outer Joins zu Bar (d.h. wo es kein b.BarId gibt für eine f.BarId ), bleibt b.IsApproved übrig als NULL für alle solchen fehlgeschlagenen Join-Zeilen, und diese Zeilen werden dann herausgefiltert.

Eine andere Sichtweise ist, dass für die erste Abfrage LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) gibt immer die LEFT-Tabellenzeilen zurück, da LEFT OUTER JOIN garantiert, dass die LEFT-Tabellenzeilen zurückgegeben werden, selbst wenn der Join fehlschlägt. Allerdings wirkt sich das Hinzufügen von (b.IsApproved = 1) aus zum LEFT OUTER JOIN Eine Bedingung ist, alle rechten Tabellenspalten auf NULL zu setzen, wenn (b.IsApproved = 1) falsch ist, d. h. nach denselben Regeln, die normalerweise auf einen LEFT JOIN angewendet werden Bedingung für (b.BarId = f.BarId) .

Aktualisieren :Um die von Conrad gestellte Frage zu vervollständigen, wäre der entsprechende LOJ für einen OPTIONALEN Filter:

SELECT * 
FROM Foo f 
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);

d.h. das WHERE -Klausel muss sowohl die Bedingung berücksichtigen, ob der Join (NULL) fehlschlägt und der Filter ignoriert werden soll, und wo die Verknüpfung erfolgreich ist und der Filter angewendet werden muss. (b.IsApproved oder b.BarId könnte auf NULL getestet werden )

Ich habe hier ein SqlFiddle zusammengestellt, das die Unterschiede zwischen den verschiedenen Platzierungen des b.IsApproved demonstriert Filter relativ zum JOIN .