Wees voorzichtig met het verschil met outer joins. Een query waarbij een filter van b.IsApproved
(in de rechter tabel, Bar) is toegevoegd aan de ON
staat van de JOIN
:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
Is NIET hetzelfde als het plaatsen van het filter in de WHERE
clausule:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Sinds voor 'mislukte' outer joins naar Bar
(d.w.z. waar er geen b.BarId
. is voor een f.BarId
), laat dit b.IsApproved
als NULL
voor al dergelijke mislukte samenvoegrijen, en deze rijen worden dan uitgefilterd.
Een andere manier om dit te bekijken is dat voor de eerste zoekopdracht, LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId)
zal altijd de LEFT tabelrijen retourneren, aangezien LEFT OUTER JOIN
garandeert dat de LEFT-tabelrijen worden geretourneerd, zelfs als de join mislukt. Het effect van het toevoegen van (b.IsApproved = 1)
naar de LEFT OUTER JOIN
op voorwaarde is om alle rechter tabelkolommen NULL te geven wanneer (b.IsApproved = 1)
is onwaar, d.w.z. volgens dezelfde regels die normaal worden toegepast op een LEFT JOIN
voorwaarde op (b.BarId = f.BarId)
.
Bijwerken :Om de vraag van Conrad te beantwoorden, zou de equivalente LOJ voor een OPTIONEEL filter zijn:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
d.w.z. de WHERE
clausule moet rekening houden met zowel de voorwaarde of de join mislukt (NULL)
en het filter moet worden genegeerd, en waar de samenvoeging slaagt en het filter moet worden toegepast. (b.IsApproved
of b.BarId
kan worden getest op NULL
)
Ik heb hier een SqlFiddle samengesteld die de verschillen laat zien tussen de verschillende plaatsingen van de b.IsApproved
filter ten opzichte van de JOIN
.