Ontem me deparei com uma questão um tanto quanto interessante…
Qual o resultado das queries abaixo? Elas são equivalentes???
Query 1:
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT * FROM ( SELECT 1 col1 UNION SELECT 2 UNION SELECT 3 ) T1 LEFT JOIN ( SELECT 1 col1 UNION SELECT 3 ) T2 ON t1.col1 = t2.col1 WHERE t2.col1 IS NULL |
Query 2:
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT * FROM ( SELECT 1 col1 UNION SELECT 2 UNION SELECT 3 ) T1 LEFT JOIN ( SELECT 1 col1 UNION SELECT 3 ) T2 ON t1.col1 = t2.col1 AND t2.col1 IS NULL |
Passando o olho rapidamente, parece ser a mesma coisa, mas reparem na última linha, a única diferença entre elas é o uso do where e o outro existe somente o join.
Bom, a resposta é: Não, elas não são equivalentes… o resultado é completamente diferente!!
Execute no SSMS e veja.
Mas agora vamos ao “Mas porque isso acontece?”
Isso ocorre pois quando o SQL Server processa um join, a engine escolhe o método mais eficiente de processá-la. Apesar da execução física de vários joins utilizar diferentes formas de otimização, a sequência (sem trema) lógica é:
1. A condição do join na cláusula FROM é aplicada.
2. A condição do join e a condição da busca da cláusula WHERE é aplicada.
3. a condição da busca da cláusula HAVING é aplicada.
Esta sequência pode às vezes influenciar no resultado de uma query se condições são movidas entre a cláusula FROM e a WHERE.
Referência do estudo: Join Fundamentals
A segunda consulta é equivalente à consulta abaixo, que mostra de form
a mais clara o resultado vazio que é T2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
SELECT * FROM ( SELECT 1 col1 UNION SELECT 2 UNION SELECT 3 ) T1 LEFT JOIN ( SELECT * FROM ( SELECT 1 col1 UNION SELECT 3 ) S WHERE S.col1 IS NULL ) T2 ON t1.col1 = t2.col1 |