Em primeiro lugar, para ser completamente equivalente, a primeira consulta deveria ter sido escrita
SELECT mw.*,
nvs.*
FROM mst_words mw
LEFT JOIN (SELECT *
FROM vocab_stats
WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no
WHERE (nvs.correct > 0 )
AND mw.level = 1
Assim, mw.* e nvs.* juntos produzem o mesmo conjunto que o singular * da 2ª consulta. A consulta como você escreveu pode usar um INNER JOIN, pois inclui um filtro em nvs.correct.
A forma geral
TABLEA LEFT JOIN TABLEB ON <CONDITION>
attempts
para localizar registros da Tabela B com base na condição. Se falhar, os resultados de TABLEA são mantidos, com todas as colunas de TableB definidas como NULL. Em contraste TABLEA INNER JOIN TABLEB ON <CONDITION>
também
attempts
para localizar registros da Tabela B com base na condição. No entanto , quando falha, o registro específico da TabelaA é removido do conjunto de resultados de saída. O padrão ANSI para CROSS JOIN produz um produto cartesiano entre as duas mesas.
TABLEA CROSS JOIN TABLEB
-- # or in older syntax, simply using commas
TABLEA, TABLEB
A intenção da sintaxe é que CADA linha em TABLEA seja unida a CADA linha em TABLEB. Portanto, 4 linhas em A e 3 linhas em B produzem 12 linhas de saída. Quando emparelhado com condições na cláusula WHERE, às vezes produz o mesmo comportamento do INNER JOIN, pois expressam a mesma coisa (condição entre A e B => manter ou não). No entanto, é muito mais claro ao ler a intenção quando você usa INNER JOIN em vez de vírgulas.
Em termos de desempenho, a maioria dos DBMS processará uma junção LEFT mais rapidamente do que uma INNER JOIN. A notação de vírgula pode fazer com que os sistemas de banco de dados interpretem mal a intenção e produzam um plano de consulta ruim - portanto, outra vantagem para a notação SQL92.
Por que precisamos de LEFT JOIN? Se a explicação de LEFT JOIN acima ainda não for suficiente (manter registros em A sem correspondências em B), considere que para obter o mesmo, você precisaria de um UNION complexo entre dois conjuntos usando a antiga notação de vírgula para obter o mesmo efeito . Mas como dito anteriormente , isso não se aplica ao seu exemplo, que é realmente um INNER JOIN escondido atrás de um LEFT JOIN.
Notas:
- O RIGHT JOIN é o mesmo que LEFT, exceto que começa com TABLEB (lado direito) em vez de A.
- RIGHT e LEFT JOINS são junções OUTER. A palavra OUTER é opcional, ou seja, pode ser escrita como
LEFT OUTER JOIN
. - O terceiro tipo de junção OUTER é a junção FULL OUTER, mas isso não é discutido aqui.