Eu tenho uma consulta que se parece com isso:
SELECT *
FROM TBLA A
LEFT JOIN TBLB B ON A.Col1 = B.Col2
RIGHT JOIN TBLC C ON B.Col3 = C.Col4
JOIN TBLD D ON C.Col5 = D.Col6
Em que ordem as junções serão resolvidas? Estou mais interessado no SQL Server e vou marcar uma explicação para ele como resposta, mas estou igualmente interessado no padrão ANSI/ISO e como ele funciona nos vários RDBMS.
O motivo dessa pergunta era descobrir por que os resultados diferiam dessa consulta
SELECT *
FROM TBLA A
CROSS JOIN TBLC C
LEFT JOIN TBLB B ON A.Col1 = B.Col2 AND B.Col3 = C.Col4
JOIN TBLD D ON C.Col5 = D.Col6
Logicamente , as junções são resolvidas na ordem das
ON
cláusulas da esquerda para a direita.A saída de cada junção é uma tabela virtual que vai para a próxima junção.
Portanto, para a consulta em sua pergunta, o resultado da tabela virtual de
A LJ B
é unido à direita emC
. A condição de junção deB.Col3 = C.Col4
perderá todas as linhas estendidas nulas preservadas pela junção esquerda original, transformando efetivamente a primeira junção de volta em uma junção interna e a tabela virtual resultante (que preserva todas as linhas deC
) é então unida internamente emD
.Portanto, sua consulta inicial pode ser simplificada como
O que é efetivamente o mesmo que
(A IJ B) ROJ (C IJ D)
A ordem das
ON
cláusulas não é necessariamente a mesma ordem em que as tabelas aparecem na consulta. Isso também poderia ser reescrito como(C IJ D) LOJ (A IJ B)
A posição das cláusulas on significa que a junção externa é realizada entre as duas tabelas virtuais resultantes
(C IJ D)
e(A IJ B)
não apenas em uma única tabela.Em sua segunda consulta, conceitualmente, a tabela virtual
A x C
é deixada unida em B preservando todo o produto cartesiano, então o resultado disso é unidoD
ao predicadoC.Col5 = D.Col6
. Isso elimina todas as linhas do resultado final que não se juntam internamenteC
eD
significa que é equivalente aNo PostgreSQL:
http://www.postgresql.org/docs/9.1/static/sql-select.html#SQL-FROM