A maioria dos dialetos SQL aceita as seguintes consultas:
SELECT a.foo, b.foo
FROM a, b
WHERE a.x = b.x
SELECT a.foo, b.foo
FROM a
LEFT JOIN b ON a.x = b.x
Agora, obviamente, quando você precisa de uma associação externa, a segunda sintaxe é necessária. Mas, ao fazer uma junção interna, por que devo preferir a segunda sintaxe à primeira (ou vice-versa)?
Respostas:
A sintaxe antiga, com apenas a listagem das tabelas e o uso da
WHERE
cláusula para especificar os critérios de junção, está sendo preterida na maioria dos bancos de dados modernos.Não é apenas para mostrar, a sintaxe antiga tem a possibilidade de ser ambígua quando você usa junções INNER e OUTER na mesma consulta.
Deixe-me lhe dar um exemplo.
Vamos supor que você tenha 3 tabelas no seu sistema:
Cada tabela contém várias linhas, vinculadas. Você tem várias empresas e cada empresa pode ter vários departamentos e cada departamento pode ter vários funcionários.
Ok, agora você quer fazer o seguinte:
Então você faz isso:
Observe que o último existe uma junção interna, para atender aos critérios de que você deseja apenas departamentos com pessoas.
Ok, então o que acontece agora. Bem, o problema é que depende do mecanismo do banco de dados, do otimizador de consulta, índices e estatísticas da tabela. Deixe-me explicar.
Se o otimizador de consultas determinar que a maneira de fazer isso é primeiro contratar uma empresa, encontrar os departamentos e fazer uma junção interna com os funcionários, você não terá empresas que não tenham departamentos.
A razão para isso é que a
WHERE
cláusula determina quais linhas terminam no resultado final, não partes individuais das linhas.E, nesse caso, devido à junção esquerda, a coluna Department.ID será NULL e, portanto, quando se trata de INNER JOIN to Employee, não há como atender a essa restrição para a linha Employee e, portanto, não aparecer.
Por outro lado, se o otimizador de consultas decidir atacar a junção departamento-funcionário primeiro e depois fazer uma junção esquerda com as empresas, você as verá.
Portanto, a sintaxe antiga é ambígua. Não há como especificar o que você deseja, sem lidar com dicas de consulta, e alguns bancos de dados não têm como.
Digite a nova sintaxe, com isso você pode escolher.
Por exemplo, se você deseja todas as empresas, como a descrição do problema afirmou, é isso que você escreveria:
Aqui você especifica que deseja que a junção departamento-funcionário seja feita como uma junção e, em seguida, deixa a junção dos resultados disso com as empresas.
Além disso, digamos que você queira apenas departamentos que contenham a letra X em seus nomes. Novamente, com as junções de estilo antigo, você corre o risco de perder a empresa também, se ela não tiver departamentos com um X no nome, mas com a nova sintaxe, você poderá fazer o seguinte:
Essa cláusula extra é usada para a união, mas não é um filtro para a linha inteira. Portanto, a linha pode aparecer com informações da empresa, mas pode ter NULLs em todas as colunas de departamento e funcionário dessa linha, porque não há departamento com um X no nome dessa empresa. Isso é difícil com a sintaxe antiga.
É por isso que, entre outros fornecedores, a Microsoft descontinuou a sintaxe de junção externa antiga, mas não a sintaxe de junção interna antiga, desde o SQL Server 2005 e superior. A única maneira de conversar com um banco de dados em execução no Microsoft SQL Server 2005 ou 2008, usando a sintaxe de junção externa do estilo antigo, é defini-lo no modo de compatibilidade 8.0 (também conhecido como SQL Server 2000).
Além disso, da maneira antiga, jogando várias tabelas no otimizador de consultas, com várias cláusulas WHERE, era semelhante a dizer "aqui está você, faça o melhor que puder". Com a nova sintaxe, o otimizador de consulta tem menos trabalho a fazer para descobrir quais partes estão juntas.
Então aí está.
ESQUERDA e INTERIOR JOIN é a onda do futuro.
fonte
OUTER JOIN
sintaxe nunca padrão*=
/=*
/*=*
está obsoleta.A sintaxe JOIN mantém as condições próximas à tabela à qual se aplicam. Isso é especialmente útil quando você ingressa em uma grande quantidade de tabelas.
A propósito, você também pode fazer uma junção externa com a primeira sintaxe:
Ou
Ou
fonte
A primeira maneira é o padrão mais antigo. O segundo método foi introduzido no SQL-92, http://en.wikipedia.org/wiki/SQL . O padrão completo pode ser visto em http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt .
Levou muitos anos para as empresas de banco de dados adotarem o padrão SQL-92.
Portanto, a razão pela qual o segundo método é preferido, é o padrão SQL de acordo com o comitê de padrões ANSI e ISO.
fonte
,
ainda é padrão.on
precisavam ser introduzidos apenasouter join
uma vez que as sub-seleções também foram introduzidas.Basicamente, quando sua cláusula FROM lista tabelas da seguinte maneira:
o resultado é um produto cruzado de todas as linhas nas tabelas A, B, C. Em seguida, você aplica a restrição
WHERE tableA.id = tableB.a_id
que descartará um grande número de linhas e depois ...AND tableB.id = tableC.b_id
e você deve obter apenas as linhas que realmente lhe interessam no.Os DBMSs sabem como otimizar esse SQL para que a diferença de desempenho ao escrever isso usando JOINs seja insignificante (se houver). O uso da notação JOIN torna a instrução SQL mais legível (IMHO, não usar junções transforma a instrução em uma bagunça). Usando o produto cruzado, é necessário fornecer critérios de junção na cláusula WHERE, e esse é o problema com a notação. Você está lotando sua cláusula WHERE com coisas como
que é usado apenas para restringir o produto cruzado. A cláusula WHERE deve conter apenas RESTRIÇÕES ao conjunto de resultados. Se você combinar critérios de junção de tabela com restrições do conjunto de resultados, você (e outros) achará sua consulta mais difícil de ler. Você definitivamente deve usar JOINs e manter a cláusula FROM uma cláusula FROM e a cláusula WHERE uma cláusula WHERE.
fonte
O segundo é preferido porque é muito menos provável que resulte em uma junção cruzada acidental, esquecendo de colocar na cláusula where. Uma junção sem cláusula on falhará na verificação de sintaxe, uma junção de estilo antigo sem cláusula where não falhará, fará uma junção cruzada.
Além disso, quando mais tarde você precisar fazer uma junção esquerda, é útil para manutenção que todos estejam na mesma estrutura. E a sintaxe antiga está desatualizada desde 1992, é hora de parar de usá-la.
Além disso, descobri que muitas pessoas que usam exclusivamente a primeira sintaxe não entendem realmente as junções e a compreensão das junções é essencial para obter resultados corretos ao consultar.
fonte
Eu acho que existem algumas boas razões nesta página para adotar o segundo método - usando JOINs explícitos. O argumento decisivo é que, quando os critérios JOIN são removidos da cláusula WHERE, fica muito mais fácil ver os demais critérios de seleção na cláusula WHERE.
Em instruções SELECT realmente complexas, fica muito mais fácil para o leitor entender o que está acontecendo.
fonte
A
SELECT * FROM table1, table2, ...
sintaxe está correta para algumas tabelas, mas se torna exponencialmente ( não necessariamente uma declaração matematicamente precisa) ) cada vez mais difícil de ler à medida que o número de tabelas aumenta.A sintaxe JOIN é mais difícil de escrever (no início), mas torna explícito quais critérios afetam quais tabelas. Isso torna muito mais difícil cometer um erro.
Além disso, se todas as junções forem INNER, as duas versões serão equivalentes. No entanto, no momento em que você tem uma junção EXTERNA em qualquer lugar da declaração, as coisas ficam muito mais complicadas e é praticamente garantido que o que você escreve não estará consultando o que acha que escreveu.
fonte
Quando você precisa de uma junção externa, a segunda sintaxe não é sempre é necessária:
Oráculo:
MSSQLServer (embora tenha sido descontinuado na versão 2000) / Sybase:
Mas voltando à sua pergunta. Não sei a resposta, mas provavelmente está relacionada ao fato de uma associação ser mais natural (pelo menos sintaticamente) do que adicionar uma expressão a uma cláusula where quando você está fazendo exatamente isso: união .
fonte
Eu ouço muitas pessoas reclamando que o primeiro é muito difícil de entender e que não está claro. Não vejo problema com isso, mas depois de ter essa discussão, uso a segunda até no INNER JOINS para maior clareza.
fonte
Para o banco de dados, eles acabam sendo os mesmos. Para você, porém, você terá que usar essa segunda sintaxe em algumas situações. Por questões de edição de consultas que acabam tendo que usá-lo (descobrindo que você precisava de uma junção esquerda onde você tinha uma junção direta) e, por questões de consistência, eu usaria apenas o segundo método. Isso tornará as consultas de leitura mais fáceis.
fonte
Bem, a primeira e a segunda consultas podem gerar resultados diferentes porque um LEFT JOIN inclui todos os registros da primeira tabela, mesmo se não houver registros correspondentes na tabela correta.
fonte