Após a leitura, isso não é uma duplicata das junções explícitas vs implícitas do SQL . A resposta pode estar relacionada (ou mesmo a mesma), mas a pergunta é diferente.
Qual é a diferença e o que deve acontecer em cada uma?
Se eu entendi a teoria corretamente, o otimizador de consulta deve poder usar os dois de forma intercambiável.
Respostas:
Eles não são a mesma coisa.
Considere estas consultas:
e
O primeiro retornará um pedido e suas linhas, se houver, para o número do pedido
12345
. O segundo retornará todos os pedidos, mas somente o pedido12345
terá linhas associadas a ele.Com um
INNER JOIN
, as cláusulas são efetivamente equivalentes. No entanto, apenas porque eles são funcionalmente iguais, na medida em que produzem os mesmos resultados, não significa que os dois tipos de cláusulas tenham o mesmo significado semântico.fonte
Matérias para junções externas
uma.
WHERE
cláusula: Após ingressar. Os registros serão filtrados após a associação.b.
ON
Cláusula - Antes de ingressar. Os registros (da tabela à direita) serão filtrados antes da associação. Isso pode acabar como nulo no resultado (desde a junção OUTER).Exemplo : considere as tabelas abaixo:
a)
WHERE
Cláusula interna :b)
JOIN
Cláusula internafonte
intermediate join table
? Algum comando 'Explain'?Em
INNER JOIN
s, eles são intercambiáveis e o otimizador os reorganizará à vontade.Em
OUTER JOIN
s, eles não são necessariamente intercambiáveis, dependendo de qual lado da junção eles dependem.Coloquei-os em qualquer lugar, dependendo da legibilidade.
fonte
Orders.Join( OrderLines, x => x.ID, x => OrderID, (o,l) => new {Orders = o, Lines = l}).Where( ol => ol.Orders.ID = 12345)
O jeito que eu faço é:
Sempre coloque as condições de junção na
ON
cláusula se você estiver executando umINNER JOIN
. Portanto, não inclua nenhuma condição WHERE na cláusula ON, coloque-a naWHERE
cláusulaSe você estiver fazendo a
LEFT JOIN
, adicione quaisquer condições WHERE àON
cláusula da tabela no lado direito da junção. Isso é obrigatório, pois adicionar uma cláusula WHERE que faça referência ao lado direito da junção converterá a junção em INNER JOIN.A exceção é quando você está procurando os registros que não estão em uma tabela específica. Você gostaria de acrescentar a referência a um identificador único (que não é sempre NULL) na RIGHT JOIN tabela para a cláusula WHERE da seguinte forma:
WHERE t2.idfield IS NULL
. Portanto, a única vez em que você deve fazer referência a uma tabela no lado direito da junção é encontrar os registros que não estão na tabela.fonte
Em uma junção interna, eles significam a mesma coisa. No entanto, você obterá resultados diferentes em uma associação externa, dependendo se você colocar a condição de associação na cláusula WHERE vs ON. Dê uma olhada nesta pergunta relacionada e nesta resposta (por mim).
Eu acho que faz mais sentido ter o hábito de sempre colocar a condição de junção na cláusula ON (a menos que seja uma junção externa e você realmente a queira na cláusula where), pois fica mais claro para quem lê sua consulta em que condições as tabelas estão sendo unidas e também ajuda a impedir que a cláusula WHERE tenha dezenas de linhas.
fonte
Relação de tabela
Considerando que temos o seguinte
post
epost_comment
tabelas:O
post
possui os seguintes registros:e o
post_comment
tem as seguintes três linhas:SQL INNER JOIN
A cláusula SQL JOIN permite associar linhas que pertencem a tabelas diferentes. Por exemplo, um CROSS JOIN criará um produto cartesiano contendo todas as combinações possíveis de linhas entre as duas tabelas de junção.
Embora o CROSS JOIN seja útil em determinados cenários, na maioria das vezes, você deseja ingressar em tabelas com base em uma condição específica. E é aí que o INNER JOIN entra em cena.
O SQL INNER JOIN nos permite filtrar o produto cartesiano da união de duas tabelas com base em uma condição especificada através da cláusula ON.
SQL INNER JOIN - ON "condição sempre verdadeira"
Se você fornecer uma condição "sempre verdadeira", o INNER JOIN não filtrará os registros unidos e o conjunto de resultados conterá o Produto Cartesiano das duas tabelas de junção.
Por exemplo, se executarmos a seguinte consulta SQL INNER JOIN:
Obteremos todas as combinações de
post
epost_comment
registros:Portanto, se a condição da cláusula ON for "sempre verdadeira", o INNER JOIN será simplesmente equivalente a uma consulta CROSS JOIN:
SQL INNER JOIN - ON "condição sempre falsa"
Por outro lado, se a condição da cláusula ON for "sempre falsa", todos os registros associados serão filtrados e o conjunto de resultados ficará vazio.
Portanto, se executarmos a seguinte consulta SQL INNER JOIN:
Não obteremos nenhum resultado de volta:
Isso ocorre porque a consulta acima é equivalente à seguinte consulta CROSS JOIN:
Cláusula SQL INNER JOIN - ON usando as colunas Chave Externa e Chave Primária
A condição da cláusula ON mais comum é aquela que corresponde à coluna Chave estrangeira na tabela filha com a coluna Chave primária na tabela pai, conforme ilustrado pela seguinte consulta:
Ao executar a consulta SQL INNER JOIN acima, obtemos o seguinte conjunto de resultados:
Portanto, apenas os registros que correspondem à condição da cláusula ON são incluídos no conjunto de resultados da consulta. No nosso caso, o conjunto de resultados contém todos os
post
seuspost_comment
registros. Aspost
linhas que não têm associaçãopost_comment
são excluídas, pois não podem satisfazer a condição da cláusula ON.Novamente, a consulta SQL INNER JOIN acima é equivalente à seguinte consulta CROSS JOIN:
As linhas não marcadas são as que satisfazem a cláusula WHERE, e somente esses registros serão incluídos no conjunto de resultados. Essa é a melhor maneira de visualizar como a cláusula INNER JOIN funciona.
Conclusão
Uma instrução INNER JOIN pode ser reescrita como CROSS JOIN com uma cláusula WHERE que corresponde à mesma condição usada na cláusula ON da consulta INNER JOIN.
fonte
Há uma grande diferença entre a cláusula where vs. on , quando se trata da junção esquerda.
Aqui está um exemplo:
Há fid é id da tabela t2.
Consulta sobre "na cláusula":
Consulta na "cláusula where":
É claro que, a primeira consulta retorna um registro de t1 e sua linha dependente de t2, se houver, para a linha t1.v = 'K'.
A segunda consulta retorna linhas de t1, mas apenas para t1.v = 'K' terá qualquer linha associada a ela.
fonte
Em termos do otimizador, não deve fazer diferença se você define suas cláusulas de junção com ON ou WHERE.
No entanto, IMHO, acho muito mais claro usar a cláusula ON ao executar junções. Dessa forma, você tem uma seção específica de sua consulta que determina como a junção é manipulada versus misturada com o restante das cláusulas WHERE.
fonte
Vamos considerar essas tabelas:
UMA
B
id_A
sendo uma chave estrangeira para a tabelaA
Escrevendo esta consulta:
Fornecerá este resultado:
O que está em A, mas não em B, significa que há valores nulos para B.
Agora, vamos considerar uma parte específica
B.id_A
e destacá-la do resultado anterior:Escrevendo esta consulta:
Fornecerá este resultado:
Como isso remove na junção interna os valores que não estão no
B.id_A = SpecificPart
Agora, vamos mudar a consulta para isso:
O resultado é agora:
Como todo o resultado é filtrado contra a
B.id_A = SpecificPart
remoção das peçasB.id_A = NULL
, que estão no A que não estão no Bfonte
Você está tentando juntar dados ou filtrar dados?
Para facilitar a leitura, faz mais sentido isolar esses casos de uso como ON e WHERE, respectivamente.
Pode ser muito difícil ler uma consulta em que a condição JOIN e a condição de filtragem existam na cláusula WHERE.
Em termos de desempenho, você não deve ver a diferença, embora tipos diferentes de SQL às vezes lidem com o planejamento de consultas de maneira diferente, para que possa valer a pena tentar
¯\_(ツ)_/¯
(lembre-se do cache afetando a velocidade da consulta)Além disso, como outros observaram, se você usar uma junção externa, obterá resultados diferentes se colocar a condição de filtro na cláusula ON porque ela afeta apenas uma das tabelas.
Escrevi um post mais detalhado sobre isso aqui: https://dataschool.com/learn/difference-between-where-and-on-in-sql
fonte
No SQL, a cláusula 'WHERE' e 'ON' são tipos de Statemants Condicionais, mas a principal diferença entre eles é a cláusula 'Where' que é usada nas Instruções de Seleção / Atualização para especificar as Condições, enquanto a cláusula 'ON' é usado em Junções, onde verifica ou verifica se os Registros são Correspondidos nas tabelas de destino e de origem, antes que as Tabelas sejam Associadas
Por exemplo: - 'WHERE'
Por exemplo: - 'ON'
Existem duas tabelas employee e employee_details, as colunas correspondentes são employee_id.
Espero ter respondido sua pergunta. Reverta para qualquer esclarecimento.
fonte
WHERE
no lugar deON
, não é? sqlfiddle.com/#!2/ae5b0/14/0Eu acho que é o efeito da sequência de junção. No caso de junção superior esquerda, o SQL faz a junção esquerda primeiro e depois faz o filtro. No caso inferior, localize Orders.ID = 12345 primeiro e depois ingresse.
fonte
Para uma junção interna,
WHERE
eON
pode ser usado de forma intercambiável. De fato, é possível usarON
em uma subconsulta correlacionada. Por exemplo:Isso é (IMHO) totalmente confuso para um humano, e é muito fácil esquecer de vincular
table1
a qualquer coisa (porque a tabela "driver" não possui uma cláusula "on"), mas é legal.fonte
para obter um melhor desempenho, as tabelas devem ter uma coluna indexada especial a ser usada para JOINS.
Portanto, se a coluna que você condicionar não for uma daquelas colunas indexadas, suspeito que seja melhor mantê-la em WHERE.
para que você JOIN use as colunas indexadas, depois de JOIN, execute a condição na coluna nenhuma indexada.
fonte
Normalmente, a filtragem é processada na cláusula WHERE depois que as duas tabelas já foram unidas. É possível, embora você queira filtrar uma ou ambas as tabelas antes de ingressar nelas. ou seja, a cláusula where se aplica a todo o conjunto de resultados, enquanto a cláusula on se aplica apenas à junção em questão.
fonte
Eu acho que essa distinção pode ser melhor explicada através da ordem lógica das operações no SQL , que é simplificada:
FROM
(incluindo junções)WHERE
GROUP BY
HAVING
WINDOW
SELECT
DISTINCT
UNION
,INTERSECT
,EXCEPT
ORDER BY
OFFSET
FETCH
Associações não são uma cláusula da instrução select, mas um operador dentro de
FROM
. Como tal, todas asON
cláusulas pertencentes aoJOIN
operador correspondente "já aconteceram" logicamente quando o processamento lógico chega àWHERE
cláusula. Isso significa que, no caso de umaLEFT JOIN
, por exemplo, a semântica da junção externa já aconteceu no momento em que aWHERE
cláusula é aplicada.Expliquei o exemplo a seguir com mais detalhes nesta postagem do blog . Ao executar esta consulta:
O
LEFT JOIN
realmente não tem qualquer efeito útil, porque, mesmo se um ator não jogar em um filme, o ator será filtrada, comoFILM_ID
seráNULL
eoWHERE
cláusula irá filtrar tais linha a. O resultado é algo como:Ou seja, como se nos juntássemos às duas mesas. Se movermos o predicado de filtro na
ON
cláusula, ele se tornará um critério para a junção externa:Ou seja, o resultado conterá atores sem nenhum filme ou sem filmes com
FILM_ID < 10
Em resumo
Sempre coloque seu predicado onde faz mais sentido, logicamente.
fonte
Quanto à sua pergunta,
É o mesmo 'on' ou 'where' em uma junção interna, desde que o servidor possa obtê-lo:
e
A opção 'where' nem todos os intérpretes sabem, portanto talvez deva ser evitada. E, claro, a cláusula 'on' é mais clara.
fonte
Esta é a minha solução.
Você deve ter a
GROUP BY
obtê-lo para o trabalho.Espero que esta ajuda.
fonte