Qual é a diferença entre uma junção interna e uma junção externa?

35

Eu sou novo no SQL e queria saber qual é a diferença entre esses dois JOINtipos?

SELECT * 
FROM user u
INNER JOIN telephone t ON t.user_id = u.id

SELECT * 
FROM user u
LEFT OUTER JOIN telephone t ON t.user_id = u.id

Quando devo usar um ou outro?

Julien
fonte
6
isso se encaixa como uma pergunta de DBA? Isso parece mais uma pergunta de codificação para mim.
BlackICE
11
@ David seus pensamentos sobre Meta
Sathyajith Bhat
@ David, em seguida, VtC, se você acha que é errado para o site. Sempre podemos reabrir.
jcolebrand
3
Eu acho que essa é uma ótima pergunta e muito apropriada para o site.
datagod
essa necessidade de ser movido para fora da DBA uneless um DBA Noob mangas até afinar o desempenho DB: P
AMDB

Respostas:

32
  • Uma junção interna selecionará apenas registros onde as chaves associadas estão nas duas tabelas especificadas.
  • Uma junção externa esquerda selecionará todos os registros da primeira tabela e quaisquer registros na segunda tabela que correspondam às chaves unidas.
  • Uma junção externa direita selecionará todos os registros da segunda tabela e quaisquer registros na primeira tabela que correspondam às chaves unidas.

No seu primeiro exemplo, você retornará apenas uma lista de usuários e números de telefone se houver pelo menos um registro telefônico para o usuário.

No seu segundo exemplo, você retornará uma lista de todos os usuários, além de todos os registros telefônicos, se estiverem disponíveis (se não estiverem disponíveis, você obterá NULLos valores do telefone).

LittleBobbyTables
fonte
13

Sempre que alguém faz essa pergunta, existe a resposta: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Espero que ajude você a entender,

Spredzy
fonte
3
Eu trabalho com junções há 20 anos e esses diagramas me pareciam confusos.
Hogan
3
Estou com @Hogan - os diagramas ven não são a melhor explicação para isso .. uma grade mostrando quais combinações seriam retornadas provavelmente seria melhor.
Joe
Tudo o que mostra é que você não entende um diagrama de Venn. Eles se relacionam perfeitamente com os tipos de união, mas lembre-se de que são uma ferramenta para ajudar a entender os novos membros. Se você já aprendeu a se unir a um conceito diferente, é provável que isso lhe pareça desconhecido. Isso não é problema, mas também não é um bom indicador para a utilidade dos diagramas.
JamesRyan
@jamesryan isso não é verdade, eles não se relacionam perfeitamente, as junções são semelhantes ao produto cartesiano de conjuntos, não à interseção e união, o analógico do diagrama de venn funciona apenas se você estiver juntando chaves únicas, se tiver chaves duplicadas e perderá o aspecto do produto cartesiano.
Será
11
Discordo totalmente, os diagramas de venn já têm uma interpretação muito bem definida, estabelecem interseção e união. Junções não se encaixam nessa interpretação quando você une chaves não exclusivas. Eu acho que você interpreta os diagramas de Venn de maneira muito ampla.
Will
8

Uma junção interna retorna linhas que podem ser combinadas com base nos critérios de junção.
Uma junção externa retorna essas e todas as linhas ...
   ... da primeira tabela para uma junção esquerda
   ... da segunda tabela para uma junção direita
   ... das duas tabelas para uma junção completa

Escolher quando usar um ou outro é uma questão de determinar quais dados você precisa. Para o seu exemplo, se você precisar apenas de registros com user_ids do telefone que correspondam aos IDs do usuário, use a junção interna. Se você também deseja incluir linhas do usuário que não possuem entrada telefônica correspondente, a associação à esquerda seria apropriada.

Para mais informações, consulte esta pergunta no StackOverflow .

Leigh Riffel
fonte
7

Se você tem 2 tabelas como abaixo:

Table1 :   A1    B1          Table2  :    B2     C2 
           -     -                        -      -
           1     2                        1      1
           2     4                        2      4
           3     5                        5      2

Se você usa o Inner Join, você obtém:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2

Se você usa a Junção externa completa, obtém:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL
NULL   NULL    1       1

Se você usa a associação externa esquerda, você obtém:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL
Am1rr3zA
fonte
6

A junção externa é expressamente projetada para produzir nulos em seu resultado e, portanto, deve ser evitada, em geral. Relativamente falando, é um tipo de casamento de espingarda: força as tabelas a um tipo de união - sim, quero dizer união, não união - mesmo quando as tabelas em questão falham em conformidade com os requisitos usuais de união. Isso é feito, preenchendo uma ou ambas as tabelas com nulos antes de fazer a união, tornando-as conformes aos requisitos usuais, afinal. Mas não há razão para que esse preenchimento não deva ser feito com valores adequados em vez de nulos, como neste exemplo:

SELECT SNO , PNO 
FROM   SP 
UNION  
SELECT SNO , 'nil' AS PNO 
FROM   S 
WHERE  SNO NOT IN ( SELECT SNO FROM SP )

Como alternativa, o mesmo resultado pode ser obtido usando o operador de junção externa do SQL em conjunto com COALESCE, como aqui:

SELECT SNO , COALESCE ( PNO , 'nil' ) AS PNO 
FROM ( S NATURAL LEFT OUTER JOIN SP ) AS TEMP

Uma observação sobre a junção externa (4.6) em "SQL e teoria relacional: como escrever código SQL preciso" por data de CJ

um dia quando
fonte
5

Uma junção interna é uma junção em que os únicos resultados exibidos são aqueles em que as chaves estão nas duas tabelas. Uma junção externa exibirá os resultados para todas as chaves em uma tabela, uma junção esquerda da primeira e uma junção direita da segunda. Por exemplo:

Digamos que a tabela1 tenha os seguintes pares de dados e chave primária: (1, a), (2, b), (3, c)

Digamos também que a tabela2 tenha os seguintes pares de dados e chave primária: (1, divertido), (3, pode), (4, acontecer)

Portanto, uma junção interna da tabela1 à tabela2 nas chaves primárias produziria os seguintes trigêmeos resultantes (com a chave primária comum primeiro, o segundo item da primeira tabela em segundo e o segundo item da segunda tabela em terceiro): (1, a, fun), ( 3, c) pode)

Uma junção externa esquerda da tabela1 para a tabela2 nas chaves primárias produziria os seguintes trigêmeos resultantes (mesmo formato acima): (1, a, fun), (2, b, NULL), (3, c, can)

Uma junção externa direita da tabela1 para a tabela2 nas chaves primárias produziria os seguintes trigêmeos resultantes (mesmo formato acima): (1, a, divertido), (3, c, pode), (4, NULL, acontecer)

Espero que isso explique bem o conceito decentemente.

indyK1ng
fonte
4

Deixe-me tentar descrevê-lo um pouco mais intuitivo.

A junção interna mostra os usuários, que têm um ou mais telefones junto com seus números de telefone.

A junção externa esquerda lista adicionalmente os 'usuários' que não têm telefone.

bernd_k
fonte
4

Como você perguntou quando usar o quê, eis um cenário com consultas - selecione qual usar, dependendo do requisito.

Dados:

Usuários da tabela possui 10 registros. A Tabela Phoneno possui 6 registros (com uma relação 1: 1, o que significa que uma entrada no PhoneNo fará referência a apenas uma entrada em Usuários e apenas uma entrada no PhoneNo pode fazer referência a uma entrada especificada em Usuários).

Requisito 1: mostre todos os usuários com seus números de telefone. Ignore usuários sem número de telefone.

Inquerir:

SELECT u.uid, u.name, p.phonno 
  FROM user u 
INNER JOIN phones p ON p.uid = u.uid

Resultado: mostra 6 usuários que têm número de telefone

Requisito 2: mostre todos os usuários com seu número de telefone. Se o usuário não tiver um telefone exibindo 'N / A' (não disponível)

Inquerir:

SELECT u.uid, u.name, ifnull(p.phonno,'N/A') 
  FROM user u 
LEFT OUTER JOIN phones p ON p.uid = u.uid

Resultado:

Mostra todos os 10 registros

Nota: ifnull é uma sintaxe do MySql para transformar o valor nulo. Eu usei essa função para fazer o mecanismo db mostrar 'N / A' quando phonno é nulo. Procure a função apropriada se você estiver usando algum outro DBMS. No SQL Server, você precisa usar a CASEinstrução

Eu espero que isso ajude.

AmDB
fonte