Bare vær forsigtig med forskellen med ydre sammenføjninger. En forespørgsel, hvor et filter på b.IsApproved
(på den højre tabel, Bar) tilføjes til ON
betingelse for JOIN
:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
Er IKKE det samme som at placere filteret i WHERE
klausul:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Siden for 'mislykkedes' ydre joinforbindelser til Bar
(dvs. hvor der ikke er nogen b.BarId
for en f.BarId
), vil dette efterlade b.IsApproved
som NULL
for alle sådanne mislykkede join-rækker, og disse rækker vil så blive filtreret fra.
En anden måde at se dette på er, at for den første forespørgsel, LEFT OUTER JOIN Bar b ON (b.IsApproved =1) AND (b.BarId =f.BarId)
vil altid returnere de VENSTRE tabelrækker, da LEFT OUTER JOIN
garanterer, at de VENSTRE tabelrækker vil blive returneret, selvom sammenkædningen mislykkes. Men effekten af at tilføje (b.IsApproved =1)
til LEFT OUTER JOIN
on condition er at nulstille eventuelle højre tabelkolonner, når (b.IsApproved =1)
er falsk, dvs. i henhold til de samme regler, der normalt gælder for en LEFT JOIN
betingelse på (b.BarId =f.BarId)
.
Opdater :For at fuldføre spørgsmålet stillet af Conrad vil den tilsvarende LOJ for et VALGFRI filter være:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
dvs. (NULL)
og filteret skal ignoreres, og hvor sammenføjningen lykkes, og filteret skal anvendes. (b.IsApproved
eller b.BarId
kunne testes for NULL
)
Jeg har sat en SqlFiddle sammen her, som viser forskellene mellem de forskellige placeringer af b.IsApproved
filter i forhold til JOIN
.