Qual é a diferença entre "INNER JOIN" e "OUTER JOIN"?


4672

Também como LEFT JOIN, RIGHT JOINe se FULL JOINencaixa?


64
Das respostas e comentários e suas referências abaixo, apenas um realmente explica como os diagramas de Venn representam os operadores: A área de interseção do círculo representa o conjunto de linhas em A JOIN B. as linhas da tabela que não participam de A JOIN B e adicionam as colunas exclusivas à outra tabela, todas definidas como NULL. (E o mais dar uma correspondência falsa vaga dos círculos para A e B.)
philipxy

1
Saltando das respostas baseadas na teoria abaixo, para um aplicativo do mundo real: freqüentemente trabalho com dados de experimentos, executando benchmarks em projetos de processadores. Muitas vezes, desejo comparar os resultados entre 2 ou mais opções de hardware. INNER JOIN significa que apenas vejo os benchmarks que foram executados com sucesso em todas as experiências; OUTER JOIN significa que posso ver todos os experimentos, incluindo aqueles que não foram executados em algumas configurações. É importante ver falhas nessas experiências, bem como sucessos. Bastante importante que eu escrevi PerlSQL para obter OUTER JOIN, quando muitos RDBMSes faltava-lo,
Krazy Glew

4
Muitas respostas já foram fornecidas, mas este tutorial não foi mencionado. Se você conhece os diagramas de Venn, este é um ótimo tutorial: blog.codinghorror.com/a-visual-explanation-of-sql-joins Para mim, é conciso o suficiente para ser uma leitura rápida, mas ainda assim capta todo o conceito e funciona todo o processo. casos muito bem. Se você não souber o que são os diagramas de Venn, aprenda-os. Leva de 5 a 10 minutos para fazê-lo e ajudará sempre que você precisar visualizar o trabalho com conjuntos e gerenciar operações em conjuntos.
DanteTheSmith #

15
@DanteTheSmith Não, isso sofre dos mesmos problemas que os diagramas aqui. Veja meu comentário acima sobre a pergunta e abaixo sobre a mesma postagem no blog: "Jeff repudia o blog dele algumas páginas abaixo nos comentários". Os diagramas de Venn mostram elementos em conjuntos. Apenas tente identificar exatamente quais são os conjuntos e quais são os elementos nesses diagramas. Os conjuntos não são as tabelas e os elementos não são suas linhas. Além disso, quaisquer duas tabelas podem ser unidas, portanto, PKs e FKs são irrelevantes. Tudo falso. Você está fazendo exatamente o que milhares de outras pessoas fizeram - teve uma vaga impressão que (erroneamente) supõe que faz sentido.
Philipxy #

3
Chris Eu recomendo que você leia este artigo: towardsdatascience.com/… ... e considere alterar sua opção de resposta aceita (talvez para a que possui a recompensa) para uma resposta que não use os diagramas de Venn. A resposta atualmente aceita engana muitas pessoas. Peço que você faça isso para o bem da nossa comunidade e a qualidade da nossa base de conhecimento.
Colm Bhandal

Respostas:


6115

Supondo que você esteja ingressando em colunas sem duplicatas, é um caso muito comum:

  • Uma junção interna de A e B fornece o resultado da interseção A, ou seja, a parte interna de uma interseção do diagrama de Venn .

  • Uma junção externa de A e B fornece os resultados da união A, ou seja, as partes externas de uma união do diagrama de Venn.

Exemplos

Suponha que você tenha duas tabelas, com uma única coluna cada, e os dados da seguinte maneira:

A    B
-    -
1    3
2    4
3    5
4    6

Observe que (1,2) são únicos para A, (3,4) são comuns e (5,6) são únicos para B.

Junção interna

Uma junção interna usando uma das consultas equivalentes fornece a interseção das duas tabelas, ou seja, as duas linhas que elas têm em comum.

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

a | b
--+--
3 | 3
4 | 4

Junção externa esquerda

Uma junção externa esquerda fornecerá todas as linhas em A, mais as linhas comuns em B.

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4

Junção externa direita

Uma junção externa direita fornecerá todas as linhas em B, mais as linhas comuns em A.

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6

Junção externa completa

Uma junção externa completa fornecerá a união de A e B, ou seja, todas as linhas em A e todas as linhas em B. Se algo em A não tiver um dado correspondente em B, a parte B será nula e vice-versa. versa.

select * from a FULL OUTER JOIN b on a.a = b.b;

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5

42
Seria bom aumentar o exemplo adicionando outra linha na tabela B com o valor 4. Isso mostrará que as junções internas não precisam ter o mesmo número de linhas.
softveda

473
Uma excelente explicação, no entanto, esta afirmação: Uma junção externa de A e B fornece os resultados da união A, ou seja, as partes externas de uma união do diagrama de venn. não é redigido com precisão. Uma junção externa fornecerá os resultados de A interseção B, além de um dos seguintes: todos A (junção esquerda), todos B (junção direita) ou todos os A e todos os B (junção completa). Somente este último cenário é realmente uma união B. Ainda assim, uma explicação bem escrita.
Thomas

11
Estou certo de que FULL JOIN é um alias de FULL OUTER JOIN e LEFT JOIN é um alias de LEFT OUTTER JOIN?
Damian

3
Sim, ótima e excelente explicação. mas por que na coluna b os valores não estão em ordem? ou seja, é 6,5 não como 5,6?
Ameer

7
@ Ammeer, Obrigado. A associação não garante um pedido, você precisará adicionar uma cláusula ORDER BY.
Mark Harrison

734

Os diagramas de Venn realmente não fazem isso por mim.

Eles não mostram nenhuma distinção entre uma junção cruzada e uma junção interna, por exemplo, ou geralmente mostram qualquer distinção entre diferentes tipos de predicado de junção ou fornecem uma estrutura para raciocinar sobre como eles irão operar.

Não há substituto para a compreensão do processamento lógico e é relativamente simples de entender de qualquer maneira.

  1. Imagine uma junção cruzada.
  2. Avalie a oncláusula em todas as linhas da etapa 1, mantendo aquelas nas quais o predicado avalia comotrue
  3. (Apenas para associações externas), adicione novamente as linhas externas que foram perdidas na etapa 2.

(Observação: na prática, o otimizador de consulta pode encontrar maneiras mais eficientes de executar a consulta do que a descrição puramente lógica acima, mas o resultado final deve ser o mesmo)

Vou começar com uma versão animada de uma junção externa completa . Mais explicações a seguir.

insira a descrição da imagem aqui


Explicação

Tabelas de origem

insira a descrição do link aqui

Comece primeiro com um CROSS JOIN(produto cartesiano AKA). Isso não possui uma ONcláusula e simplesmente retorna todas as combinações de linhas das duas tabelas.

SELECIONE A.Cor, B.Cor A partir de uma junção cruzada B

insira a descrição do link aqui

Associações interna e externa têm um predicado de cláusula "ON".

  • Junção interna. Avalie a condição na cláusula "ON" para todas as linhas no resultado da junção cruzada. Se true, retorne a linha unida. Caso contrário, descarte-o.
  • Junção externa esquerda. O mesmo que junção interna para todas as linhas na tabela esquerda que não corresponderem a nada produzidas com valores NULL para as colunas da tabela direita.
  • Junção externa direita. O mesmo que junção interna, em seguida, para todas as linhas na tabela à direita que não corresponderem a nada produzem essas com valores NULL para as colunas da tabela esquerda.
  • Junção externa completa. Igual à junção interna, preserve as linhas esquerdas não correspondentes, como na junção externa esquerda e as linhas direita não correspondentes, conforme a junção externa direita.

Alguns exemplos

SELECIONE A.Colour, B.Colour A PARTIR DE UMA UNIDADE INTERIOR B EM A.Colour = B.Colour

A descrição acima é a junção equi clássica.

Junção interna

Versão Animada

insira a descrição da imagem aqui

SELECIONE A.Cor, B.Cor A partir de uma junção interna B em A.Cor NÃO IN ('Verde', 'Azul')

A condição de junção interna não precisa necessariamente ser uma condição de igualdade e não precisa fazer referência a colunas de ambas (ou mesmo de uma) das tabelas. A avaliação A.Colour NOT IN ('Green','Blue')em cada linha da junção cruzada retorna.

interior 2

SELECIONE A.Cor, B.Cor A PARTIR DE UMA UNIÃO INTERIOR B EM 1 = 1

A condição de junção é avaliada como verdadeira para todas as linhas no resultado da junção cruzada, portanto, é exatamente o mesmo que uma junção cruzada. Não vou repetir a imagem das 16 linhas novamente.

SELECIONE A.Cor, B.Cor A partir de uma junção externa esquerda B em A.Cor = B.Cor

Junções externas são avaliadas logicamente da mesma maneira que junções internas, exceto se uma linha da tabela esquerda (para uma junção esquerda) não se unir a nenhuma linha da tabela à direita, ela é preservada no resultado com NULLvalores para o colunas da direita.

LOJ

SELECIONE A.Cor, B.Cor A partir de uma junção externa esquerda B em A.Cor = B.Cor WHERE B.Cor É NULL

Isso simplesmente restringe o resultado anterior para retornar apenas as linhas onde B.Colour IS NULL. Nesse caso em particular, essas serão as linhas que foram preservadas, pois não tinham correspondência na tabela à direita e a consulta retorna a única linha vermelha que não corresponde à tabela B. Isso é conhecido como uma junção anti-semi.

É importante selecionar uma coluna para o IS NULLteste que não seja anulável ou para o qual a condição de junção garanta a NULLexclusão de quaisquer valores para que esse padrão funcione corretamente e evite apenas trazer de volta as linhas que possuem um NULLvalor para esse padrão. coluna, além das linhas não correspondidas.

loj é nulo

SELECIONE A.Cor, B.Cor A PARTIR DE UMA JUNTA EXTERIOR CERTA B EM A.Cor = B.Cor

As junções externas à direita agem de maneira semelhante às junções externas à esquerda, exceto que preservam linhas não correspondentes da tabela direita e estendem nulo as colunas à esquerda.

ROJ

SELECIONE A.Colour, B.Colour DE UMA JUNTA EXTERNA COMPLETA B EM A.Colour = B.Colour

As junções externas completas combinam o comportamento das junções esquerda e direita e preservam as linhas não correspondentes das tabelas esquerda e direita.

FOJ

SELECIONE A.Cor, B. Cor DE UMA JUNTA EXTERNA COMPLETA B ON 1 = 0

Nenhuma linha na junção cruzada corresponde ao 1=0predicado. Todas as linhas de ambos os lados são preservadas usando regras normais de junção externa com NULL nas colunas da tabela do outro lado.

FOJ 2

SELECIONAR COALESCE (A.Cor, B.Colour) como cor de uma junção externa completa B ON 1 = 0

Com uma pequena alteração na consulta anterior, era possível simular uma UNION ALLdas duas tabelas.

UNIÃO TUDO

SELECIONE A.Cor, B.Cor A partir de uma junção externa esquerda B em A.Cor = B.Cor WHERE B.Cor = 'Verde'

Observe que a WHEREcláusula (se presente) é executada logicamente após a associação. Um erro comum é executar uma junção externa esquerda e incluir uma cláusula WHERE com uma condição na tabela direita que acaba excluindo as linhas não correspondentes. O exemplo acima acaba executando a junção externa ...

LOJ

... E então a cláusula "Where" é executada. NULL= 'Green'não é avaliado como verdadeiro, de modo que a linha preservada pela junção externa acaba sendo descartada (junto com a azul) efetivamente convertendo a junção novamente em interna.

LOJtoInner

Se a intenção fosse incluir apenas linhas de B, em que Cor é Verde, e todas as linhas de A, independentemente da sintaxe correta.

SELECIONE A.Cor, B.Cor A partir de uma junção externa esquerda B em A.Cor = B.Cor e B.Cor = 'Verde'

insira a descrição da imagem aqui

SQL Fiddle

Veja estes exemplos executados ao vivo no SQLFiddle.com .


46
Vou dizer que, embora isso não funcione para mim tão bem quanto os diagramas de Venn, eu aprecio que as pessoas variem e aprendam de maneira diferente, e essa é uma explicação muito bem apresentada, diferente de qualquer outra que eu já vi antes, então eu apoio o @ypercube em concedendo os pontos de bônus. Também é um bom trabalho explicando a diferença de colocar condições adicionais na cláusula JOIN versus a cláusula WHERE. Parabéns a você, Martin Smith.
Old Pro

22
@OldPro Os diagramas de Venn são bons na medida em que suponho, mas eles não falam sobre como representar uma junção cruzada ou para diferenciar um tipo de predicado de junção, como junção equi de outro. O modelo mental de avaliar o predicado de junção em cada linha do resultado da junção cruzada e, em seguida, adicionar novamente em linhas sem correspondência uma junção externa e, finalmente, avaliar o local onde funciona melhor para mim.
Martin Smith

18
Os diagramas de Venn são bons para representar uniões e interseções e diferenças, mas não se juntam. Eles têm algum valor educacional menor para junções muito simples, ou seja, junções onde a condição de junção está em colunas únicas.
ypercubeᵀᴹ

12
@ Arthur - Não, você está errado. SQL Fiddle sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/5155 isso é algo que os diagramas de Venn não podem ilustrar.
Martin Smith

7
@MartinSmith Uau, concordo, estou totalmente errado! Demasiado acostumado a trabalhar com one-to-manys .. obrigado pela correção.
Arth

188

As junções são usadas para combinar os dados de duas tabelas, com o resultado sendo uma nova tabela temporária. As junções são realizadas com base em algo chamado predicado, que especifica a condição a ser usada para realizar uma junção. A diferença entre uma junção interna e uma junção externa é que uma junção interna retornará apenas as linhas que realmente correspondem com base no predicado da junção. Por exemplo: vamos considerar a tabela Empregado e Local:

insira a descrição da imagem aqui

Junção interna: - A junção interna cria uma nova tabela de resultados combinando os valores da coluna de duas tabelas ( Funcionário e Local ) com base no predicado de junção. A consulta compara cada linha de Employee com cada linha de Location para encontrar todos os pares de linhas que satisfazem o predicado de junção. Quando o predicado de junção é satisfeito pela correspondência de valores não NULL, os valores da coluna para cada par de linhas correspondentes de Employee e Location são combinados em uma linha de resultado. Aqui está a aparência do SQL para uma junção interna:

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

Agora, aqui está como seria o resultado da execução desse SQL: insira a descrição da imagem aqui

Associação externa: - Uma associação externa não exige que cada registro nas duas tabelas associadas tenha um registro correspondente. A tabela unida retém cada registro - mesmo que não exista outro registro correspondente. As junções externas subdividem-se ainda mais em junções externas esquerdas e externas, dependendo de quais linhas da tabela são mantidas (esquerda ou direita).

Junção Externa Esquerda: - O resultado de uma junção externa esquerda (ou simplesmente junção esquerda) para as tabelas Employee e Location sempre contém todos os registros da tabela "esquerda" ( Employee ), mesmo que a condição de junção não encontre nenhum registro correspondente em a tabela "certa" ( localização ). Aqui está a aparência do SQL para uma junção externa esquerda, usando as tabelas acima:

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

Agora, aqui está como seria o resultado da execução desse SQL: insira a descrição da imagem aqui

Junção externa direita: - Uma junção externa direita (ou junção direita) se assemelha bastante a uma junção externa esquerda, exceto com o tratamento das tabelas invertidas. Cada linha da tabela "direita" ( Local ) aparecerá na tabela unida pelo menos uma vez. Se não existir nenhuma linha correspondente da tabela "esquerda" ( Funcionário ), NULL aparecerá nas colunas de Funcionário para os registros que não têm correspondência no Local . É assim que o SQL se parece:

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

Usando as tabelas acima, podemos mostrar como seria o conjunto de resultados de uma junção externa direita:

insira a descrição da imagem aqui

Junções externas completas: - Junção externa completa ou Junção completa serve para reter as informações não correspondentes incluindo linhas não correspondentes nos resultados de uma junção, use uma junção externa completa. Inclui todas as linhas de ambas as tabelas, independentemente de a outra tabela ter ou não um valor correspondente.

Fonte da imagem

Manual de Referência do MySQL 8.0 - Sintaxe de junção

Operações do Oracle Join


3
melhor resposta até agora, sintaxe alternativa - é o que eu estava procurando, obrigado!
Joey

1
Os diagramas de Venn estão incorretos. Veja meus comentários sobre a pergunta e outras respostas. Também a maior parte dessa linguagem é ruim. Por exemplo: "Quando o predicado de junção é satisfeito pela correspondência de valores diferentes de NULL, os valores da coluna para cada par correspondente de linhas de Funcionário e Local são combinados em uma linha de resultado." Não, não "Quando o predicado de junção é satisfeito por valores diferentes de NULL". Os valores nas linhas não importam se a condição como um todo é verdadeira ou falsa. Alguns valores podem muito bem ser NULL para uma condição verdadeira.
Philipxy #

Embora não seja explicitamente declarado, os diagramas são de Venn. Os diagramas de Venn não são, em geral, a caracterização matemática correta de uma junção. Sugiro remover os diagramas de Venn.
Colm Bhandal

@ColmBhandal: diagramas de Venn removidos
ajitksharma

Por favor, use o texto, não imagens / links para o texto - incluindo mesas e ERDs . Use imagens apenas para o que não pode ser expresso como texto ou para aumentar o texto. As imagens não podem ser pesquisadas ou recortadas e coladas. Inclua uma legenda / chave e explicação em uma imagem.
philipxy

133

Junção interna

Recupere apenas as linhas correspondentes, ou seja A intersect B,.

Digite a descrição da imagem aqui

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Junção externa esquerda

Selecione todos os registros da primeira tabela e quaisquer registros na segunda tabela que correspondam às chaves unidas.

Digite a descrição da imagem aqui

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Junção externa completa

Selecione todos os registros da segunda tabela e quaisquer registros na primeira tabela que correspondam às chaves unidas.

Digite a descrição da imagem aqui

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Referências


14
Qual é o nome da ferramenta? Acho que é interessante, pois mostra o número de linhas e diagramas de Venn
Grijesh Chauhan

2
@GrijeshChauhan Sim, mas você pode tentar executá-lo usando vinho .
Tushar Gupta - curioustus

2
Ohh! sim eu .. eu usei o SQLyog usando o vinho .. também existe o PlayOnLinux
Grijesh Chauhan

1
Seu texto não está claro e está errado. As "somente linhas correspondidas" são linhas da junção cruzada de A e B e o que é recuperado (uma junção interna B) não é uma interseção B, mas (uma junção esquerda B) se cruzam (uma junção direita B). O "selecionado" linhas não são de A & B, eles são de cruz uma junção B & de valores nulos estendida de linhas de A & B.
philipxy

@ TusharGupta-curioustushar, você deve incluir as "Tabelas usadas para exemplos SQL"
Manuel Jordan

112

Em palavras simples:

Uma junção interna recupera apenas as linhas correspondentes.

Enquanto uma junção externa recupera as linhas correspondentes de uma tabela e todas as linhas da outra tabela .... o resultado depende de qual você está usando:

  • Esquerda : linhas correspondentes na tabela direita e todas as linhas na tabela esquerda

  • Direita : linhas correspondentes na tabela esquerda e todas as linhas na tabela direita ou

  • Completo : todas as linhas em todas as tabelas. Não importa se há uma correspondência ou não


1
@nomen Não é que esta resposta o resolva, mas INNER JOIN é uma interseção e FULL OUTTER JOIN é a UNIÃO correspondente se os conjuntos / círculos esquerdo e direito contiverem as linhas de união (esquerda) e direita (respectivamente). PS Esta resposta não é clara sobre as linhas de entrada versus saída. Ele confunde "na tabela esquerda / direita" com "tem uma parte esquerda / direita na esquerda / direita" e usa "linha correspondente" vs "tudo" para significar a linha estendida por linha de outra tabela vs por valores nulos.
philipxy

104

Uma junção interna mostra apenas linhas se houver um registro correspondente no outro lado (direito) da junção.

Uma junção externa (esquerda) mostra linhas para cada registro no lado esquerdo, mesmo se não houver linhas correspondentes no outro lado (direito) da junção. Se não houver linha correspondente, as colunas do outro lado (direito) mostrariam NULLs.


82

Associações internas exigem que um registro com um ID relacionado exista na tabela associada.

As junções externas retornarão registros para o lado esquerdo, mesmo que não exista nada para o lado direito.

Por exemplo, você tem uma tabela Orders e uma OrderDetails. Eles são relacionados por um "CódigoDoPedido".

Encomendas

  • OrderID
  • Nome do cliente

Detalhes do pedido

  • OrderDetailID
  • OrderID
  • Nome do Produto
  • Qtde
  • Preço

O pedido

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

retornará apenas pedidos que também possuem algo na tabela OrderDetails.

Se você alterá-lo para OUTER LEFT JOIN

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

em seguida, ele retornará registros da tabela Pedidos, mesmo que eles não tenham registros OrderDetails.

Você pode usar isso para encontrar pedidos que não possuem nenhum OrderDetails indicando um possível pedido órfão adicionando uma cláusula where como WHERE OrderDetails.OrderID IS NULL.


1
Agradeço o exemplo simples, mas realista. Eu mudei um pedido como SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASCpara SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC(MySQL) com sucesso. Eu não tinha certeza sobre as condições adicionais, eles misturam bem ...
PhiLho

68

Em palavras simples:

Junção interna -> Obtenha SOMENTE registros comuns das tabelas pai e filho WHERE a chave primária da tabela pai corresponde à chave estrangeira na tabela filho.

Associação à esquerda ->

pseudo-código

1.Take All records from left Table
2.for(each record in right table,) {
    if(Records from left & right table matching on primary & foreign key){
       use their values as it is as result of join at the right side for 2nd table.
    } else {
       put value NULL values in that particular record as result of join at the right side for 2nd table.
    }
  }

Junção direita : exatamente o oposto da junção esquerda. Coloque o nome da tabela em LEFT JOIN no lado direito em Right join, você obtém a mesma saída que LEFT JOIN.

Junção externa : mostra todos os registros nas duas tabelasNo matter what . Se os registros na tabela Esquerda não corresponderem à tabela direita com base na chave Primária e Externa, use o valor NULL como resultado da associação.

Exemplo:

Exemplo

Vamos assumir agora para 2 tabelas

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

Aqui, a tabela employee é a tabela Master, phone_numbers_employees é a tabela filho (ela contém uma emp_idchave estrangeira que conecta employee.idsua tabela filho).

Junções internas

Pegue os registros de 2 tabelas SOMENTE SE A chave primária da tabela de funcionários (seu ID) corresponde à chave estrangeira da tabela filho phone_numbers_employees (emp_id) .

Portanto, a consulta seria:

SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Aqui, pegue apenas as linhas correspondentes na chave primária = chave estrangeira, conforme explicado acima. Aqui, as linhas não correspondentes na chave primária = chave estrangeira são ignoradas como resultado da junção.

Junções à esquerda :

A junção esquerda mantém todas as linhas da tabela esquerda, independentemente de haver uma linha que corresponda à tabela direita.

SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Junções externas :

SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;

Diagramaticamente, ele se parece com:

Diagrama


4
O resultado não tem nada a ver com chaves primárias / exclusivas / candidatas e chaves estrangeiras. O baviour pode e deve ser descrito sem referência a eles. Uma junção cruzada é calculada e as linhas que não correspondem à condição ON são filtradas; adicionalmente para as junções externas linhas filtradas / linhas sem correspondência são estendidos por nulos (por esquerda / direita / CHEIO e incluídos.
philipxy

A suposição de que as junções SQL são sempre correspondentes às chaves primárias / estrangeiras está levando ao uso indevido dos diagramas de Venn. Revise sua resposta de acordo.
Colm Bhandal

58

Você usa INNER JOINpara retornar todas as linhas das duas tabelas em que há uma correspondência. ou seja, na tabela resultante, todas as linhas e colunas terão valores.

Na OUTER JOINtabela resultante pode ter colunas vazias. A junção externa pode ser LEFTou RIGHT.

LEFT OUTER JOIN retorna todas as linhas da primeira tabela, mesmo se não houver correspondências na segunda tabela.

RIGHT OUTER JOIN retorna todas as linhas da segunda tabela, mesmo se não houver correspondências na primeira tabela.



54

INNER JOINrequer que haja pelo menos uma correspondência na comparação das duas tabelas. Por exemplo, a tabela A e a tabela B, que implica A ٨ B (interseção A).

LEFT OUTER JOIN e LEFT JOIN são iguais. Ele fornece todos os registros correspondentes nas duas tabelas e todas as possibilidades da tabela esquerda.

Da mesma forma, RIGHT OUTER JOINe RIGHT JOINsão os mesmos. Ele fornece todos os registros correspondentes nas duas tabelas e todas as possibilidades da tabela correta.

FULL JOINé a combinação de LEFT OUTER JOINe RIGHT OUTER JOINsem duplicação.


43

A resposta está no significado de cada um, assim nos resultados.

Nota:
Em SQLitenão existe RIGHT OUTER JOINou FULL OUTER JOIN.
E também MySQLnão há FULL OUTER JOIN.

Minha resposta é baseada na nota acima .

Quando você tem duas tabelas como estas:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

CROSS JOIN / OUTTER JOIN:
Você pode ter todos esses dados de tabelas com CROSS JOINou apenas os ,seguintes:

SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2
1  | a1   | 3  | b2
2  | b1   | 1  | a2
2  | b1   | 3  | b2

INNER JOIN:
Quando você deseja adicionar um filtro aos resultados acima com base em uma relação como a que table1.id = table2.idvocê pode usar INNER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id | name 
---+------+----+------
1  | a1   | 1  | a2

ESQUERDA [EXTERNA] JOIN:
Quando você quiser ter todas as linhas de uma das tabelas no resultado acima, com a mesma relação, poderá usar LEFT JOIN:
(Para RIGHT JOIN, basta mudar o local das tabelas)

SELECT * FROM table1, table2 WHERE table1.id = table2.id 
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id

--[Results:]
id | name | id   | name 
---+------+------+------
1  | a1   | 1    | a2
2  | b1   | Null | Null

JUNÇÃO EXTERNA COMPLETA:
Quando você também quiser ter todas as linhas da outra tabela em seus resultados, poderá usar FULL OUTER JOIN:

SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id

--[Results:]
id   | name | id   | name 
-----+------+------+------
1    | a1   | 1    | a2
2    | b1   | Null | Null
Null | Null | 3    | b2

Bem, conforme sua necessidade, você escolhe cada uma que atenda às suas necessidades;).


Você pode adicionar à sua nota que também não existe full outer joinno MySQL.
potashin

35

Junção interna.

Uma junção está combinando as linhas de duas tabelas. Uma junção interna tenta corresponder as duas tabelas com base nos critérios especificados na consulta e retorna apenas as linhas correspondentes. Se uma linha da primeira tabela na junção corresponder a duas linhas na segunda tabela, duas linhas serão retornadas nos resultados. Se houver uma linha na primeira tabela que não corresponda a uma linha na segunda, ela não será retornada; da mesma forma, se houver uma linha na segunda tabela que não corresponda a uma linha na primeira, ela não será retornada.

Junção externa.

Uma junção esquerda tenta encontrar as linhas correspondentes da primeira tabela às linhas da segunda tabela. Se não conseguir encontrar uma correspondência, retornará as colunas da primeira tabela e deixará as colunas da segunda tabela em branco (nulo).


28

insira a descrição da imagem aqui

  • INNER JOINjunção mais típica para duas ou mais tabelas. Retorna a correspondência de dados na tabela ON primarykey e forignkey.
  • OUTER JOINé o mesmo que INNER JOIN, mas também inclui NULLdados no ResultSet.
    • LEFT JOIN= INNER JOIN+ Dados incomparáveis ​​da tabela esquerda com Nullcorrespondência na tabela direita.
    • RIGHT JOIN= INNER JOIN+ Dados incomparáveis ​​da tabela da direita com Nullcorrespondência na tabela da esquerda.
    • FULL JOIN= INNER JOIN+ Dados incomparáveis ​​nas tabelas direita e esquerda com Nullcorrespondências.
  • A junção automática não é uma palavra-chave no SQL, quando uma tabela referencia dados, por si só, conhecida como junção automática. Usando INNER JOINe OUTER JOINpodemos escrever consultas de auto-junção.

Por exemplo:

SELECT * 
FROM   tablea a 
       INNER JOIN tableb b 
               ON a.primary_key = b.foreign_key 
       INNER JOIN tablec c 
               ON b.primary_key = c.foreign_key 

27

Não vejo muitos detalhes sobre desempenho e otimizador nas outras respostas.

Às vezes é bom saber que apenas INNER JOIN é associativo, o que significa que o otimizador tem mais opções para brincar com ele. Ele pode reordenar a ordem de junção para torná-lo mais rápido, mantendo o mesmo resultado. O otimizador pode usar a maioria dos modos de junção.

Geralmente, é uma boa prática tentar usar em INNER JOINvez dos diferentes tipos de junções. (Obviamente, se for possível, considerando o conjunto de resultados esperado.)

Existem alguns bons exemplos e explicações aqui sobre esse estranho comportamento associativo:


4
Não pode ser uma "boa prática" usar um tipo de junção em detrimento de outro. A junção que você usa determina os dados que você deseja. Se você usa outro, está incorreto. Além disso, no Oracle, pelo menos, essa resposta está completamente errada. Parece completamente errado para tudo e você não tem provas. Você tem provas?
22414 Ben

1. Quero dizer, tente usar. Vi muitas pessoas usando junções esquerdas ou esquerdas em todos os lugares sem uma boa razão. (As colunas unidas eram 'não nulas'.) Nesses casos, seria definitivamente melhor usar junções INNER. 2. Adicionei um link que explica o comportamento não associativo melhor do que eu poderia.
Lajos Veres

Como eu sei INNER JOINé mais lento do que LEFT JOINna maioria das vezes, E as pessoas podem usar em LEFT JOINvez de INNER JOINadicionar um WHEREpara remover NULLresultados inesperados ;).
shA.t

Esses comentários me deixaram um pouco incerto. Por que você acha que INNERé mais lento?
Lajos Veres

Depende do motor. gnu join, joinkeys, DB2, MySQL. As armadilhas de desempenho são abundantes, como digitação solta ou uma conversão explícita.
Mckenzm

26

Tendo criticado o muito amado diagrama de Venn em tom de vermelho, achei justo postar minha própria tentativa.

Embora a resposta de @Martin Smith seja o melhor desse grupo, ele só mostra a coluna chave de cada tabela, enquanto eu acho que idealmente colunas não chave também devem ser mostradas.

O melhor que pude fazer na meia hora permitida, ainda não acho que isso mostre adequadamente que os nulos estão lá devido à ausência de valores-chave TableBou que OUTER JOINna verdade é uma união e não uma união:

insira a descrição da imagem aqui


2
A pergunta está pedindo diferença entre junções INNER e OUTER, porém, não necessariamente deixada para fora da junção externa lol
LearnByReading

@LearnByReading: minha foto à direita é uma junção externa direita, ou seja, substitua TableA a LEFT OUTER JOIN TableB bporTableB B RIGHT OUTER JOIN TableA a
onedaywhen

26

O algoritmo preciso para INNER JOIN, LEFT/RIGHT OUTER JOINsão os seguintes:

  1. Pegue cada linha da primeira tabela: a
  2. Considere todas as linhas da segunda tabela ao lado: (a, b[i])
  3. Avalie a ON ...cláusula em relação a cada par:ON( a, b[i] ) = true/false?
    • Quando a condição for avaliada true, retorne a linha combinada (a, b[i]).
    • Quando chegar ao final da segunda tabela sem nenhuma correspondência, Outer Joinretorne um par (virtual) usando Nullpara todas as colunas da outra tabela: (a, Null)para junção externa ESQUERDA ou (Null, b)junção externa DIREITA. Isso é para garantir que todas as linhas da primeira tabela existam nos resultados finais.

Nota: a condição especificada na ONcláusula pode ser qualquer coisa, não é necessário usar Chaves Primárias (e você não precisa sempre consultar as Colunas das duas tabelas)! Por exemplo:

Junção interna vs. Junção externa esquerda


insira a descrição da imagem aqui

Nota: Junção esquerda = Junção externa esquerda, Junção direita = Junção externa direita.


20

Definições mais simples

Junção interna: retorna registros correspondentes das duas tabelas.

Junção externa completa: retorna registros correspondentes e não correspondentes de ambas as tabelas com nulo para registros não correspondentes de ambas as tabelas .

Junção externa esquerda: retorna registros correspondentes e não correspondentes apenas da tabela no lado esquerdo .

União externa direita: retorna registros correspondentes e não correspondentes somente da tabela no lado direito .

Em resumo

Corresponde + Esquerda sem correspondência + Direita sem correspondência = Junção externa completa

Corresponde + Esquerda sem correspondência = Junção externa esquerda

Combinado + Direito incomparável = União externa direita

Correspondido = Junção interna


1
Isso é brilhante e explica por que a junção não funciona conforme o esperado para os índices de séries temporais. Os carimbos de hora com um segundo de diferença são incomparáveis.
yeliabsalohcin

1
@yeliabsalohcin Você não explica "como esperado" aqui ou "funciona" em seu comentário sobre a questão. É apenas um equívoco pessoal inexplicável que você estranhamente espera que os outros tenham. Se você tratar as palavras de maneira desleixada ao ler - interpretando mal a escrita clara e / ou aceitando a escrita pouco clara - como quando você está escrevendo aqui, pode esperar ter conceitos errôneos. De fato, essa resposta, como a maioria aqui, não está clara e está errada. "Junção interna: retorna registros correspondentes de ambas as tabelas" está errado quando os conjuntos de colunas de entrada diferem. Está tentando dizer alguma coisa, mas não é . (Veja a minha resposta.)
philipxy

9

Em termos simples,

1. JUNÇÃO INTERNA OU EQUI JUNTA: Retorna o conjunto de resultados que corresponde apenas à condição nas duas tabelas.

2. JUNÇÃO EXTERNA: Retorna o conjunto de resultados de todos os valores de ambas as tabelas, mesmo que haja uma condição correspondente ou não.

3. JUNTA ESQUERDA: Retorna o conjunto de resultados de todos os valores da tabela esquerda e apenas das linhas que correspondem à condição na tabela direita.

4. JUNTA CERTA: Retorna o conjunto de resultados de todos os valores da tabela direita e apenas das linhas que correspondem à condição na tabela esquerda.

5. JUNÇÃO COMPLETA: Junção completa e Junção externa completa são iguais.


5

Existem principalmente dois tipos principais de JOINs no SQL: [INNER e OUTER]


Exemplos

Suponha que você tenha duas tabelas, com uma única coluna cada, e os dados da seguinte maneira:

A    B
-    -
1    3
2    4
3    5
4    6
7
8

Observe que (1,2,7,8) são únicos para A, (3,4) são comuns e (5,6) são únicos para B.



  • (INTERNO) JUNTE - SE :

A palavra-chave INNER JOIN seleciona todas as linhas de ambas as tabelas, desde que a condição seja satisfatória. Essa palavra-chave criará o conjunto de resultados combinando todas as linhas de ambas as tabelas em que a condição satisfaz, ou seja, o valor do campo comum será o mesmo.

JUNÇÃO INTERNA

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

Resultado:

a | b
--+--
3 | 3
4 | 4


  • ESQUERDA (EXTERIOR) ADERIR :

Essa junção retorna todas as linhas da tabela no lado esquerdo da junção e as linhas correspondentes para a tabela no lado direito da junção. As linhas para as quais não há linha correspondente no lado direito, o conjunto de resultados conterá nulo. LEFT JOIN também é conhecido como LEFT OUTER JOIN.

JUNTA ESQUERDA / JUNTA ESQUERDA

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

Resultado:

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4
7 | null
8 | null


  • JUNTA DIREITA (EXTERIOR) : Retorna todos os registros da tabela da direita e os registros correspondentes da tabela da esquerda

JUNTA DIREITA / JUNTA EXTERNA DIREITA

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

Resultado:

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6


  • JUNÇÃO COMPLETA (EXTERIOR) :

    FULL JOIN cria o conjunto de resultados combinando o resultado de LEFT JOIN e RIGHT JOIN. O conjunto de resultados conterá todas as linhas das duas tabelas. As linhas para as quais não há correspondência, o conjunto de resultados conterá valores NULL.

INSCRIÇÃO COMPLETA / INSCRIÇÃO EXTERNA COMPLETA

select * from a FULL OUTER JOIN b on a.a = b.b;

Resultado:

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5
   7 | null
   8 | null

1
Os diagramas de Venn não são suficientes para descrever as junções SQL no caso geral. As junções SQL não precisam necessariamente corresponder as linhas entre as tabelas individualmente, por exemplo, usando chave estrangeira e chave primária.
Colm Bhandal

Como você junta duas mesas sem combinar a linha? Você precisa de uma chave primária ou estrangeira da coluna ou de algum campo comum para poder executar a junção. Eu estou querendo saber por que você votou negativamente nesta resposta. E o diagrama de Venn é a fonte para explicar como o SQL JOIN funciona. Você tem exemplos melhores para representar as junções? Caso contrário, faça o voto positivo, para que as pessoas obtenham melhores soluções. Obrigado.
Mayur

Você é quem colocou os diagramas no post. Qual é a legenda dos diagramas? - Quais são os elementos de cada conjunto? E quanto ao fato de que mesas são sacolas, não conjuntos? Você não diz. Uma coisa que eles não são conjuntos é de linhas de A e B pelos rótulos. Veja meus comentários nas postagens nesta página. Este post repete cegamente o uso errado visto em outro lugar, mas não entendido ou questionado. Também as coisas que você diz no texto aqui não são claras e estão erradas. Também não acrescenta nada às muitas respostas já aqui. (Embora quase todos sejam bastante pobres.) PS: Esclareça por meio de edições, não comentários.
philipxy

Os FKs não são necessários para ingressar ou consultar. Quaisquer 2 tabelas podem ser unidas em qualquer condição que envolva suas colunas e independentemente de quaisquer restrições, gatilhos ou asserções.
philipxy

3
  • Junção interna - uma junção interna usando uma das consultas equivalentes fornece a interseção das duas tabelas , ou seja, as duas linhas que elas têm em comum.

  • Junção externa esquerda - uma junção externa esquerda fornecerá todas as linhas em A, mais as linhas comuns em B.

  • Junção externa completa - Uma junção externa completa fornecerá a união de A e B, ou seja, Todas as linhas em A e todas as linhas em B. Se algo em A não tiver um dado correspondente em B, a parte B será nulo e vice-versa


1
Isso é errado e não está claro. A união não é uma interseção, a menos que as tabelas tenham as mesmas colunas. Associações externas não têm linhas de A ou B, a menos que tenham as mesmas colunas; nesse caso, não há nulos adicionados. Você está tentando dizer algo, mas não está dizendo. Você não está explicando correta ou claramente.
31517 philipxy

@ philipxy: discordou da sua declaração. Join is not an intersection unless the tables have the same columnsNão. Você pode ingressar em qualquer coluna que desejar e, se o valor corresponder, elas se unirão.
precisa saber é o seguinte

Esse comentário não é tão claro quanto sua resposta. (Suponho que você esteja pensando em algo como, o conjunto de valores de sub-sub-coluna para as colunas comuns do resultado é a interseção dos conjuntos de valores de sub-sub-subversão para as colunas comuns de cada uma das entradas; mas não foi isso que você escreveu. não é claro.)
philipxy

O que eu quis dizer foi que junção é apenas uma interseção de entradas quando é uma junção interna natural de entradas com as mesmas colunas. Você está usando as palavras "interseção" e "união" incorretamente.
philipxy

3

1. Junção interna: também chamada de Junção. Ele retorna as linhas presentes na tabela Esquerda e na tabela direita somente se houver uma correspondência . Caso contrário, ele retornará zero registros.

Exemplo:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
INNER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

output1

2. Junção externa completa: também chamada de Junção completa. Retorna todas as linhas presentes nas tabelas esquerda e direita.

Exemplo:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
FULL OUTER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

output2

3. Junção externa esquerda: ou simplesmente chamado como Junção esquerda. Retorna todas as linhas presentes na tabela esquerda e as linhas correspondentes da tabela direita (se houver).

4. Junção externa direita: também chamada de Junta direita. Ele retorna linhas correspondentes da tabela esquerda (se houver) e todas as linhas presentes na tabela Direita.

junta-se

Vantagens das junções

  1. Executa mais rapidamente.

2
Isso está correto apenas quando as tabelas têm o mesmo conjunto de colunas. (Confunde a junção interna com a interseção e a junção completa com a união.) Também "match" é indefinido. Leia meus outros comentários.
31517 philipxy

2

Considere abaixo 2 tabelas:

EMP

empid   name    dept_id salary
1       Rob     1       100
2       Mark    1       300
3       John    2       100
4       Mary    2       300
5       Bill    3       700
6       Jose    6       400

Departamento

deptid  name
1       IT
2       Accounts
3       Security
4       HR
5       R&D

Junção interna:

Principalmente escrito como JOIN em consultas sql. Retorna apenas os registros correspondentes entre as tabelas.

Descubra todos os funcionários e seus nomes de departamento:

Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security

Como você vê acima, Josenão é impresso no EMP na saída, pois o dept_id 6não encontra uma correspondência na tabela Departamento. Da mesma forma, HRe as R&Dlinhas não são impressas no Departamento tabela , pois não encontraram uma correspondência na tabela Emp.

Portanto, INNER JOIN ou apenas JOIN, retorna apenas as linhas correspondentes.

ASSOCIAÇÃO À ESQUERDA :

Isso retorna todos os registros da tabela ESQUERDA e apenas os registros correspondentes da tabela DIREITA.

Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;

empid   name    dept_name
1       Rob     IT
2       Mark    IT
3       John    Accounts
4       Mary    Accounts
5       Bill    Security
6       Jose    

Portanto, se você observar a saída acima, todos os registros da tabela ESQUERDA (Emp) serão impressos apenas com registros correspondentes da tabela DIREITA.

HRe as R&Dlinhas não são impressas na tabela Departamento , pois não encontraram uma correspondência na tabela Emp em dept_id.

Portanto, LEFT JOIN retorna TODAS as linhas da tabela Esquerda e apenas as linhas correspondentes da tabela RIGHT.

Também pode verificar a DEMO aqui .


2

A idéia geral

Por favor, veja a resposta de Martin Smith para obter melhores ilustrações e explicações sobre as diferentes junções, incluindo e especialmente as diferenças entre FULL OUTER JOIN, RIGHT OUTER JOINe LEFT OUTER JOIN.

Essas duas tabelas formam uma base para a representação dos JOINs abaixo:

Base

CROSS JOIN

CrossJoin

SELECT *
  FROM citizen
 CROSS JOIN postalcode

O resultado serão os produtos cartesianos de todas as combinações. Nenhuma JOINcondição necessária:

CrossJoinResult

JUNÇÃO INTERNA

INNER JOIN é o mesmo que simplesmente: JOIN

Junção interna

SELECT *
  FROM citizen    c
  JOIN postalcode p ON c.postal = p.postal

O resultado serão combinações que satisfazem a JOINcondição necessária :

InnerJoinResult

JUNTA EXTERNA ESQUERDA

LEFT OUTER JOIN é o mesmo que LEFT JOIN

Associação à esquerda

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal

O resultado será tudo, citizenmesmo que não haja correspondências postalcode. Novamente, uma JOINcondição é necessária:

LeftJoinResult

Dados para jogar

Todos os exemplos foram executados em um Oracle 18c. Eles estão disponíveis no dbfiddle.uk, que também é de onde vieram as capturas de tela das tabelas.

CREATE TABLE citizen (id      NUMBER,
                      name    VARCHAR2(20),
                      postal  NUMBER,  -- <-- could do with a redesign to postalcode.id instead.
                      leader  NUMBER);

CREATE TABLE postalcode (id      NUMBER,
                         postal  NUMBER,
                         city    VARCHAR2(20),
                         area    VARCHAR2(20));

INSERT INTO citizen (id, name, postal, leader)
              SELECT 1, 'Smith', 2200,  null FROM DUAL
        UNION SELECT 2, 'Green', 31006, 1    FROM DUAL
        UNION SELECT 3, 'Jensen', 623,  1    FROM DUAL;

INSERT INTO postalcode (id, postal, city, area)
                 SELECT 1, 2200,     'BigCity',         'Geancy'  FROM DUAL
           UNION SELECT 2, 31006,    'SmallTown',       'Snizkim' FROM DUAL
           UNION SELECT 3, 31006,    'Settlement',      'Moon'    FROM DUAL  -- <-- Uuh-uhh.
           UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space'   FROM DUAL;

Limites desfocados ao brincar com JOINeWHERE

CROSS JOIN

CROSS JOINresultando em linhas como A idéia geral / INNER JOIN:

SELECT *
  FROM citizen          c
  CROSS JOIN postalcode p
 WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows

Usar CROSS JOINpara obter o resultado de a LEFT OUTER JOINrequer truques como adicionar em uma NULLlinha. Está omitido.

JUNÇÃO INTERNA

INNER JOINtorna-se um produto cartesiano. É o mesmo que The General Idea / CROSS JOIN:

SELECT *
  FROM citizen    c
  JOIN postalcode p ON 1 = 1  -- < -- The ON condition makes it a CROSS JOIN

É aqui que a junção interna pode realmente ser vista como a junção cruzada com resultados que não correspondem à condição removida. Aqui, nenhuma das linhas resultantes é removida.

Usar INNER JOINpara obter o resultado de um LEFT OUTER JOINtambém requer truques. Está omitido.

JUNTA EXTERNA ESQUERDA

LEFT JOINresulta em linhas como A idéia geral / CROSS JOIN:

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN

LEFT JOINresulta em linhas como A idéia geral / INNER JOIN:

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal
 WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode

Os problemas com o diagrama de Venn

Uma pesquisa de imagens na Internet em "sql join cross inner outer" mostrará uma infinidade de diagramas de Venn. Eu costumava ter uma cópia impressa de uma na minha mesa. Mas há problemas com a representação.

O diagrama de Venn é excelente para a teoria dos conjuntos, onde um elemento pode estar em um ou nos dois conjuntos. Mas para bancos de dados, um elemento em um "conjunto" parece, para mim, uma linha em uma tabela e, portanto, também não está presente em nenhuma outra tabela. Não existe uma linha presente em várias tabelas. Uma linha é exclusiva para a tabela.

As junções automáticas são um caso de canto em que cada elemento é de fato o mesmo nos dois conjuntos. Mas ainda não está livre de nenhum dos problemas abaixo.

O conjunto Arepresenta o conjunto à esquerda (a citizentabela) e o conjunto Bé o conjunto à direita (a postalcodetabela) na discussão abaixo.

CROSS JOIN

Todos os elementos de ambos os conjuntos são combinados com todos os elementos do outro conjunto, o que significa que precisamos de Aquantidade de todos os Belementos e Bquantidade de todos os Aelementos para representar adequadamente esse produto cartesiano. A teoria dos conjuntos não é feita para vários elementos idênticos em um conjunto, então acho que os diagramas de Venn representam adequadamente impraticável / impossível. Parece que não UNIONse encaixa.

As linhas são distintas. São UNION7 linhas no total. Mas eles são incompatíveis para um SQLconjunto de resultados comum . E não é assim que CROSS JOINfunciona:

CrossJoinUnion1

Tentando representá-lo assim:

CrossJoinUnion2Crossing

..mas agora parece apenas um INTERSECTION, o que certamente não é . Além disso, não há nenhum elemento no INTERSECTIONque está realmente em qualquer um dos dois conjuntos distintos. No entanto, parece muito com os resultados pesquisáveis ​​semelhantes a este:

CrossJoinUnionUnion3

Para referência, um resultado pesquisável para CROSS JOINs pode ser visto em Tutorialgateway . O INTERSECTION, assim como este, está vazio.

JUNÇÃO INTERNA

O valor de um elemento depende da JOINcondição. É possível representar isso sob a condição de que cada linha se torne exclusiva para essa condição. O significado id=xé verdadeiro apenas para uma linha. Quando uma linha na tabela A( citizen) corresponde a várias linhas na tabela B( postalcode) sob a JOINcondição, o resultado tem os mesmos problemas que CROSS JOIN: A linha precisa ser representada várias vezes e a teoria dos conjuntos não é realmente feita para isso. Sob a condição de exclusividade, o diagrama pode funcionar, mas lembre-se de que a JOINcondição determina a colocação de um elemento no diagrama. Observando apenas os valores da JOINcondição com o restante da linha logo após o passeio:

InnerJoinIntersection - preenchido

Essa representação se desfaz completamente ao usar a INNER JOINcom uma ON 1 = 1condição que a transforma em a CROSS JOIN.

Com um self- JOIN, as linhas são de fato elementos identais em ambas as tabelas, mas representam as tabelas como ambas Ae Bnão são muito adequadas. Por exemplo, uma auto- JOINcondição comum que faz com que um elemento Acorresponda a um elemento diferente em B é ON A.parent = B.childfazer a correspondência de Apara Belementos separados. Dos exemplos que seriam SQLassim:

SELECT *
  FROM citizen c1
  JOIN citizen c2 ON c1.id = c2.leader

SelfJoinResult

Significado Smith é o líder de Green e Jensen.

JUNÇÃO EXTERNA

Novamente, os problemas começam quando uma linha possui várias correspondências com as linhas na outra tabela. Isso é ainda mais complicado, pois OUTER JOINpode corresponder ao conjunto vazio. Mas, na teoria dos conjuntos, a união de qualquer conjunto Ce de um conjunto vazio é sempre justa C. O conjunto vazio não adiciona nada. A representação disso LEFT OUTER JOINé geralmente apenas mostrando tudo Apara ilustrar que as linhas Asão selecionadas independentemente de haver uma correspondência ou não B. Os "elementos correspondentes", no entanto, têm os mesmos problemas que a ilustração acima. Eles dependem da condição. E o conjunto vazio parece ter vagado até A:

LeftJoinIntersection - preenchido

Cláusula WHERE - fazendo sentido

Localizando todas as linhas de a CROSS JOINcom Smith e código postal na Lua:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   AND p.area = 'Moon';

Onde - resultado

Agora, o diagrama de Venn não é usado para refletir o JOIN. É usado apenas para a WHEREcláusula:

Onde

..e isso faz sentido.

Quando INTERSECT e UNION fazem sentido

INTERSECT

Como explicado, um INNER JOINnão é realmente um INTERSECT. No entanto, INTERSECTs pode ser usado em resultados de consultas separadas. Aqui, um diagrama de Venn faz sentido, porque os elementos das consultas separadas são de fato linhas que pertencem a apenas um dos resultados ou a ambos. A interseção obviamente retornará apenas resultados onde a linha estiver presente nas duas consultas. Isso SQLresultará na mesma linha que a acima WHERE, e o diagrama de Venn também será o mesmo:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
INTERSECT
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

UNIÃO

Um OUTER JOINnão é um UNION. No entanto, UNIONtrabalhe nas mesmas condições que INTERSECT, resultando em um retorno de todos os resultados combinando os dois SELECTs:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
UNION
SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE p.area = 'Moon';

que é equivalente a:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   OR p.area = 'Moon';

..e fornece o resultado:

União - Resultado

Também aqui um diagrama de Venn faz sentido:

UNIÃO

Quando não se aplica

Uma observação importante é que isso só funciona quando a estrutura dos resultados dos dois SELECTs é a mesma, permitindo uma comparação ou união. Os resultados desses dois não permitirão que:

SELECT *
  FROM citizen
 WHERE name = 'Smith'
SELECT *
  FROM postalcode
 WHERE area = 'Moon';

.. tentar combinar os resultados com UNIONdá uma

ORA-01790: expression must have same datatype as corresponding expression

Para mais informações, leia Diga NÃO aos diagramas de Venn ao explicar JOINs e sql joins como diagrama de venn . Ambos também cobrem EXCEPT.


1

Há muitas boas respostas aqui com exemplos de álgebra relacional muito precisos . Aqui está uma resposta muito simplificada que pode ser útil para codificadores amadores ou iniciantes com dilemas de codificação SQL.

Basicamente, na maioria das vezes, as consultas se JOINresumem a dois casos:

Para um SELECTsubconjunto de dados A:

  • use INNER JOINquando os dados relacionados que Bvocê procura DEVEM existir por design do banco de dados;
  • use LEFT JOINquando os dados relacionados que Bvocê procura MIGHT ou MIGH NOT existem por design do banco de dados.

1

A diferença entre inner joine outer joiné a seguinte:

  1. Inner joiné uma junção que combina tabelas com base em tuplas correspondentes, enquanto que outer joiné uma junção que combina tabela com base em tuplas correspondentes e não correspondentes.
  2. Inner joinmescla a linha correspondente de duas tabelas na qual a linha não correspondente é omitida, enquanto outer joinmescla linhas de duas tabelas e as linhas não correspondentes são preenchidas com valor nulo.
  3. Inner joiné como uma operação de interseção, enquanto outer joiné como uma operação de união.
  4. Inner joinsão dois tipos, enquanto outer joinsão três tipos.
  5. outer joiné mais rápido que inner join.

1
Um resultado da junção externa é o mesmo que junção interna, mas mais algumas linhas adicionais; portanto, não faço ideia do porquê você acha que a junção externa seria mais rápida. Além disso, quais são esses "dois tipos" de junção interna? Suponho que você esteja se referindo a cheio, esquerdo e direito para exterior?
Martin Smith

1
@ M.achaibou Por favor, não faça edições que façam alterações de formato desnecessárias. Os nomes dos operadores não são código, a menos que sejam usados ​​no código. Não faça alterações para postar significado, poste um comentário para o autor. Se você não tiver o representante, aguarde até ter. Acontece que o pôster aprovou isso, mas não faça essas edições. A junção externa PS não é mais rápida que a junção interna.
philipxy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.