Efetivamente,
WHERE
condições e JOIN
condições para [INNER] JOIN
são 100% equivalentes no PostgreSQL. (É uma boa prática usar JOIN
explícito condições para tornar as consultas mais fáceis de ler e manter). O mesmo não true para um
LEFT JOIN
combinado com um WHERE
condição em uma tabela à direita da junção. A finalidade de um LEFT JOIN
é preservar todas as linhas do lado esquerdo da junção, independentemente de uma correspondência no lado direito. Se nenhuma correspondência for encontrada, a linha será estendida com NULL
valores para colunas no lado direito. O manual:
LEFT OUTER JOIN
Primeiro, uma junção interna é executada. Então, para cada linha em T1 que não satisfaça a condição de junção com nenhuma linha em T2, uma linha unida é adicionada com valores nulos nas colunas de T2. Assim, a tabela unida sempre tem pelo menos uma linha para cada linha em T1.
Se você aplicar um
WHERE
condição que requer algo além de um NULL
valor nas colunas das tabelas do lado direito, você anula o efeito e força a conversão do LEFT [OUTER] JOIN
para funcionar como um simples [INNER] JOIN
, apenas (possivelmente) mais caro devido a um plano de consulta mais complicado. Em uma consulta com muitas tabelas unidas, o Postgres (ou qualquer RDBMS) é difícil encontrar o melhor (ou mesmo um bom) plano de consulta. O número de sequências teoricamente possíveis para unir tabelas cresce fatorialmente (!). O Postgres usa o "Generic Query Optimizer" para a tarefa e existem algumas configurações para influenciá-lo.
Ofuscando a consulta com
LEFT JOIN
enganoso conforme descrito, torna o trabalho do planejador de consulta mais difícil, é enganoso para leitores humanos e normalmente sugere erros na lógica de consulta. Respostas relacionadas para problemas decorrentes disso:
- Por que null é igual a inteiro em WHERE?
- Consulta com LEFT JOIN não retornando linhas para contagem de 0
- Consulta SQL usando junção externa e limitando registros filho para cada pai
- Junta externa esquerda agindo como união interna
- Selecione as linhas que não estão presentes em outra tabela
etc.