Var bara försiktig med skillnaden med yttre skarvar. En fråga där ett filter av b.IsApproved
(på den högra tabellen, Bar) läggs till i ON
villkoret för JOIN
:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
Är INTE samma sak som att placera filtret i WHERE
klausul:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Eftersom för 'misslyckades' yttre kopplingar till Bar
(dvs. där det inte finns någon b.BarId
för en f.BarId
), lämnar detta b.IsApproved
som NULL
för alla sådana misslyckade sammanfogningsrader, och dessa rader kommer sedan att filtreras bort.
Ett annat sätt att se på detta är att för den första frågan, LEFT OUTER JOIN Bar b ON (b.IsApproved =1) AND (b.BarId =f.BarId)
kommer alltid att returnera de VÄNSTER tabellraderna, eftersom LEFT OUTER JOIN
garanterar att VÄNSTER tabellraderna kommer att returneras även om sammanfogningen misslyckas. Effekten av att lägga till (b.IsApproved =1)
till LEFT OUTER JOIN
on condition är att NULLA alla högra tabellkolumner när (b.IsApproved =1)
är falsk, det vill säga enligt samma regler som normalt tillämpas på en LEFT JOIN
villkor på (b.BarId =f.BarId)
.
Uppdatera :För att slutföra frågan från Conrad, skulle motsvarande LOJ för ett VALFRITT filter vara:
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)
och filtret ska ignoreras, och där sammanfogningen lyckas och filtret måste appliceras. (b.IsApproved
eller b.BarId
kan testas för NULL
)
Jag har satt ihop en SqlFiddle här som visar skillnaderna mellan de olika placeringarna av b.IsApproved
filter i förhållande till JOIN
.