Apenas tome cuidado com a diferença com junções externas. Uma consulta em que um filtro de
b.IsApproved (na tabela à direita, Bar) é adicionado ao ON condição do JOIN :SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
É NÃO o mesmo que colocar o filtro em
WHERE cláusula:SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Como para junções externas 'falhadas' para
Bar (ou seja, onde não há b.BarId para um f.BarId ), isso deixará b.IsApproved como NULL para todas essas linhas de junção com falha, e essas linhas serão filtradas. Outra maneira de ver isso é que, para a primeira consulta,
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) sempre retornará as linhas da tabela LEFT, pois LEFT OUTER JOIN garante que as linhas da tabela LEFT serão retornadas mesmo se a junção falhar. No entanto, o efeito de adicionar (b.IsApproved = 1) para o LEFT OUTER JOIN na condição é NULL qualquer coluna da tabela à direita quando (b.IsApproved = 1) é falso, ou seja, de acordo com as mesmas regras normalmente aplicadas a um LEFT JOIN condição em (b.BarId = f.BarId) . Atualizar :Para completar a pergunta feita por Conrad, o LOJ equivalente para um filtro OPCIONAL seria:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
ou seja, o
WHERE A cláusula precisa considerar tanto a condição se a junção falha (NULL) e o filtro deve ser ignorado e onde a junção for bem-sucedida e o filtro deve ser aplicado. (b.IsApproved ou b.BarId pode ser testado para NULL ) Eu coloquei um SqlFiddle aqui que demonstra as diferenças entre os vários posicionamentos do
b.IsApproved filtro relativo ao JOIN .