Fai solo attenzione alla differenza con i join esterni. Una query in cui è presente un filtro di b.IsApproved
(sulla tabella di destra, Bar) viene aggiunto al ON
condizione del JOIN
:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
NON come posizionare il filtro in WHERE
clausola:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Dal momento che per 'falliti' outer join a Bar
(ovvero dove non è presente b.BarId
per un f.BarId
), questo lascerà b.IsApproved
come NULL
per tutte queste righe di join non riuscite e queste righe verranno quindi filtrate.
Un altro modo di vedere questo è che per la prima query, LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId)
restituirà sempre le righe della tabella LEFT, poiché LEFT OUTER JOIN
garantisce che le righe della tabella SINISTRA verranno restituite anche se il join non riesce. Tuttavia, l'effetto dell'aggiunta di (b.IsApproved = 1)
al LEFT OUTER JOIN
a condizione è di NULL su tutte le colonne della tabella destra quando (b.IsApproved = 1)
è falso, cioè secondo le stesse regole normalmente applicate a un LEFT JOIN
condizione su (b.BarId = f.BarId)
.
Aggiorna :Per completare la domanda posta da Conrad, il LOJ equivalente per un filtro OPZIONALE sarebbe:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
cioè il WHERE
La clausola deve considerare entrambe le condizioni se il join non riesce (NULL)
e il filtro deve essere ignorato, e dove il join ha esito positivo e il filtro deve essere applicato. (b.IsApproved
o b.BarId
potrebbe essere testato per NULL
)
Ho messo insieme un SqlFiddle qui che dimostra le differenze tra i vari posizionamenti di b.IsApproved
filtro relativo al JOIN
.