MySQL: Classificação rápida dos tipos de junções


157

Eu gostaria de uma rápida descrição dos tipos de junções do MySQL. Eu sei disso, o resto não tenho certeza do que eles significam.

  • separado por vírgula (o que exatamente significa isso?):SELECT * FROM a, b WHERE b.id = a.beeId AND ...
  • mostre as informações de a, mesmo que não haja correspondências em b: SELECT * FROM a LEFT OUTER JOIN b ON b.id = a.beeId WHERE ...

Eu já vi outras junções, mas quero saber o que as torna diferentes, o que é INNER/ OUTER, adicionando LEFTcoisas de mudança.

Eu já sei como as junções funcionam, só quero saber se existem outros tipos de junções ou se são apenas maneiras diferentes de obter o mesmo resultado.


Respostas:


463

3
+1, mas ambos estão ausentes cross join, o que faz um produto cartesiano.
Denis de Bernardy

11
@denis: dê uma olhada no link codinghorror.com:There's also a cartesian product or cross join, which as far as I can tell, can't be expressed as a Venn diagram:
Rufinus

1
Estou impressionado, imprimindo esses diagramas e colocando-os na parede do meu escritório. você mudou minha vida!
Yossico

41
A questão é sobre o MySQL especificamente. O MySQL não suporta junções EXTERNAS COMPLETAS.
amigos estão

4
e, é claro, esse deve ser um motivo para não publicar este gráfico. suspirar
Rufinus

27

Com base no seu comentário, as definições simples de cada uma são encontradas melhor no W3Schools. A primeira linha de cada tipo fornece uma breve explicação do tipo de associação.

  • JOIN: retorna linhas quando houver pelo menos uma correspondência nas duas tabelas
  • LEFT JOIN: Retorna todas as linhas da tabela esquerda, mesmo se não houver correspondências na tabela direita
  • RIGHT JOIN: Retorna todas as linhas da tabela direita, mesmo se não houver correspondências na tabela esquerda
  • JUNÇÃO COMPLETA: Retornar linhas quando houver uma correspondência em uma das tabelas

EDIT FIM

Em poucas palavras, o exemplo separado por vírgula que você deu

SELECT * FROM a, b WHERE b.id = a.beeId AND ...

está selecionando todos os registros das tabelas aeb com as vírgulas separando as tabelas, isso também pode ser usado em colunas como

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...

Em seguida, ele obtém as informações instruídas na linha em que a coluna b.id e a.beeId têm correspondência no seu exemplo. Portanto, no seu exemplo, ele obterá todas as informações das tabelas aeb, onde b.id é igual a a.beeId. No meu exemplo, ele obterá todas as informações da tabela be apenas as informações da coluna a.beeName quando o b.id for igual ao a.beeId. Observe que também há uma cláusula AND, isso ajudará a refinar seus resultados.

Para alguns tutoriais simples e explicações sobre as junções esquerda e esquerda do mySQL, veja os tutoriais mySQL da Tizag. Você também pode conferir o site de Keith J. Brown para obter mais informações sobre junções, o que também é bastante bom.

Espero que isso ajude você


Acontece que eu já sei tudo isso. Na verdade, eu estava procurando os tipos de junções que existem. Desculpe por não ter esclarecido o que já sei. Mas eu não estava procurando documentação longa apenas para obter um resumo rápido.
Bryan Campo

Outra referência na resposta ... pode ser mais do que você quer, companheiro.
Ryan

+1 para essa edição. Eu não sou tendencioso contra o W3Schools como algumas pessoas parecem ser. Talvez eu não tenha visto muito os lados ruins ou talvez seja apenas uma "guerra santa". Além disso, editei o conteúdo do W3Schools, espero que você não se importe, mas fique à vontade para fazer as edições que quiser. Todos esses recursos visuais na resposta aceita são bons, mas alguns são realmente variações da mesma junção. Esta é uma boa alternativa.
Bryan Campo

Obrigado George, eu não me importo, desde que a edição esteja correta! Acredito que as pessoas precisam encontrar as fontes certas para elas, mais ou menos informações, muitos exemplos ou nenhum. As escolas do W3 são precisas e concisas, também tendem a ter bons exemplos, o Tizag é semelhante. Acalme-se, companheiro #
2110 Ryan Ryan

1
não existe JOGO COMPLETO no mysql, portanto esses links não são muito úteis.
Éter

13

Eu tenho 2 tabelas como esta:

> SELECT * FROM table_a;
+------+------+
| id   | name |
+------+------+
|    1 | row1 |
|    2 | row2 |
+------+------+

> SELECT * FROM table_b;
+------+------+------+
| id   | name | aid  |
+------+------+------+
|    3 | row3 |    1 |
|    4 | row4 |    1 |
|    5 | row5 | NULL |
+------+------+------+

INNER JOIN se preocupa com ambas as tabelas

INNER JOIN se preocupa com as duas tabelas, portanto, você só terá uma linha se ambas as tabelas tiverem uma. Se houver mais de um par correspondente, você obtém várias linhas.

> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
+------+------+------+------+------+

Não faz diferença para INNER JOIN se você reverter a ordem, porque se importa com as duas tabelas:

> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
+------+------+------+------+------+

Você obtém as mesmas linhas, mas as colunas estão em uma ordem diferente porque mencionamos as tabelas em uma ordem diferente.

LEFT JOIN se preocupa apenas com a primeira mesa

LEFT JOIN se preocupa com a primeira tabela que você fornece e não se importa muito com a segunda; portanto, você sempre obtém as linhas da primeira tabela, mesmo se não houver uma linha correspondente na segunda:

> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
|    2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+

Acima, você pode ver todas as linhas da tabela_a, mesmo que algumas não correspondam a nada na tabela b, mas nem todas as linhas da tabela_b - somente aquelas que correspondem a algo na tabela_a.

Se revertermos a ordem das tabelas, LEFT JOIN se comportará de maneira diferente:

> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
|    5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+

Agora temos todas as linhas de table_b, mas apenas as linhas correspondentes de table_a.

RIGHT JOIN se preocupa apenas com a segunda mesa

a RIGHT JOIN bfornece exatamente as mesmas linhas que b LEFT JOIN a. A única diferença é a ordem padrão das colunas.

> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
| NULL | NULL |    5 | row5 | NULL |
+------+------+------+------+------+

São as mesmas linhas table_b LEFT JOIN table_aque vimos na seção LEFT JOIN.

Similarmente:

> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
| NULL | NULL | NULL |    2 | row2 |
+------+------+------+------+------+

São as mesmas linhas que table_a LEFT JOIN table_b.

Nenhuma junção oferece cópias de tudo

Cláusula No Join: Se você escrever suas tabelas sem nenhuma cláusula JOIN, apenas separadas por vírgulas, todas as linhas da primeira tabela serão escritas ao lado de todas as linhas da segunda tabela, em todas as combinações possíveis:

> SELECT * FROM table_b, table_a;        
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    3 | row3 | 1    |    2 | row2 |
|    4 | row4 | 1    |    1 | row1 |
|    4 | row4 | 1    |    2 | row2 |
|    5 | row5 | NULL |    1 | row1 |
|    5 | row5 | NULL |    2 | row2 |
+------+------+------+------+------+

(Isto é da minha postagem no blog. Exemplos de tipos de junção SQL )


@Anu Por favor, não faça edições tão triviais quando sua baixa reputação significa que suas edições precisam ser revisadas por outras pessoas, você está perdendo tempo. Essa edição deveria ter sido rejeitada como nenhuma diferença. O código que você alterou não estava realmente errado e você poderia ter comentado.
philipxy 07/07

@philipxy Okay. Notado com isso. Enquanto tentava entender a explicação, vi um erro de digitação e, por isso, editei para torná-la mais clara. Na verdade, esta é uma boa resposta e minha intenção era mantê-la mais correta.
Anu

@Anu Esta resposta tem as mesmas descrições incompletas fragmentadas da maioria das respostas. Na verdade, não diz qual é a saída em função das entradas. Veja também quase todas as respostas na duplicata proposta e meus comentários nas duas páginas. Veja também minha resposta lá. PS: Por coincidência, acabei de ver isso no tamanho de edição revisado ontem (é claro que existem muitos outros posts relacionados no Meta Stack Overflow e no Meta Stack Exchange .)
philipxy 07/07

11

A junção externa completa não existe no mysql; talvez você precise usar uma combinação de junção esquerda e direita.

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.