Tipos de SQL JOIN Explicados
Qual é a diferença entre INNER JOIN, LEFT JOIN, RIGHT JOIN, e FULL JOIN in SQL? Quando você deve usar cada um deles? Temos suas respostas aqui mesmo.
Você quer combinar dados de duas ou mais tabelas diferentes, mas não tem certeza de como fazê-lo em SQL. Não se preocupe. Neste artigo, mostrarei a você como usar a cláusula SQL JOIN
para fundir dados de duas tabelas. Existem diferentes tipos de SQL JOIN
que você pode usar para diferentes resultados. Se você quiser aprender as diferenças entre INNER JOIN
, LEFT JOIN
, RIGHT JOIN
, e FULL JOIN
, continue lendo. Este artigo é para você.
Primeiro, vamos começar com o básico: o que é uma declaração JOIN
e como ela funciona?
O que é um SQL JOIN?
Uma cláusula JOIN
é usada quando você precisa combinar dados de duas ou mais tabelas em um conjunto de dados. Os registros de ambas as tabelas são combinados com base em uma condição (também chamada de um predicado JOIN
) que você especifica na cláusula JOIN
. Se a condição for atendida, os registros são incluídos na saída.
Neste artigo, explicarei o conceito de SQL JOIN
e os diferentes tipos de JOIN
usando exemplos. Portanto, antes de continuarmos, vamos dar uma olhada nas tabelas que vamos usar neste artigo.
Conheça o banco de dados
Vamos utilizar tabelas de um banco de dados fictício do banco. A primeira tabela é called
e contém dados relacionados às contas bancárias dos clientes:
account_id | overdraft_amt | customer_id | type_id | segment |
---|---|---|---|---|
2556889 | 12000 | 4 | 2 | RET |
1323598795 | 1550 | 1 | 1 | RET |
2225546 | 5000 | 5 | 2 | RET |
5516229 | 6000 | 4 | 5 | RET |
5356222 | 7500 | 5 | 5 | RET |
2221889 | 5400 | 1 | 2 | RET |
2455688 | 12500 | 50 | 2 | CORP |
1322488656 | 2500 | 51 | 1 | CORP |
1323598795 | 3100 | 52 | 1 | CORP |
1323111595 | 1220 | 53 | 1 | CORP |
tabela de contas
Esta tabela contém 10 registros (10 contas) e cinco colunas:
account_id
- Identifica de forma exclusiva cada conta.overdraft_amount
- O limite de saque a descoberto para cada conta.customer_id
- Identifica de forma exclusiva cada cliente.type_id
- Identifica o tipo dessa conta.segment
- Contém os valores 'RET' (para clientes de varejo) e 'CORP' (para clientes corporativos).
A segunda tabela é chamada customer
e contém dados relacionados ao cliente:
customer_id | name | lastname | gender | marital_status |
---|---|---|---|---|
1 | MARC | TESCO | M | Y |
2 | ANNA | MARTIN | F | N |
3 | EMMA | JOHNSON | F | Y |
4 | DARIO | PENTAL | M | N |
5 | ELENA | SIMSON | F | N |
6 | TIM | ROBITH | M | N |
7 | MILA | MORRIS | F | N |
8 | JENNY | DWARTH | F | Y |
tabela de clientes
Esta tabela contém oito registros e cinco colunas:
customer_id
- Identifica de forma exclusiva cada conta.name
- O primeiro nome do cliente.lastname
- O sobrenome do cliente.gender
- O sexo do cliente (M ou F).marital_status
- Se o cliente é casado (Y ou N).
Agora que temos estas duas tabelas, podemos combiná-las para exibir resultados adicionais relacionados aos dados do cliente ou da conta. JOIN
pode nos ajudar a obter respostas a perguntas como:
- Quem possui cada conta no
account
mesa? - Quantas contas Marc Tesco tem?
- Quantas contas pertencem a uma cliente do sexo feminino?
- Qual é o valor total do descoberto para todas as contas da Emma Johnson?
Para responder a cada uma dessas perguntas, precisamos combinar duas tabelas (account
e customer
) utilizando uma coluna que aparece em ambas as tabelas (neste caso, customer_id
). Uma vez fundidas as duas tabelas, teremos informações sobre contas e clientes em uma única saída.
Tenha em mente que no account
tabela, temos alguns clientes que não podem ser encontrados na customer
mesa. (Informações sobre clientes corporativos são armazenadas em outro lugar.) Além disso, tenha em mente que algumas identificações de clientes não estão presentes na tabela account
tabela; alguns clientes não têm contas.
Há várias maneiras de combinarmos duas tabelas. Ou, dito de outra forma, podemos dizer que existem vários tipos diferentes de SQL JOIN
.
Os 4 tipos de SQL JOIN
Os tipos SQL JOIN
incluem:
INNER JOIN
(também conhecido como um 'simples'JOIN
). Este é o tipo mais comum de JOIN.LEFT JOIN
(ouLEFT OUTER JOIN
)RIGHT JOIN
(ouRIGHT OUTER JOIN
)FULL JOIN
(ouFULL OUTER JOIN
)- Auto-ajustes e cruzamentos também são possíveis em SQL, mas não vamos falar sobre eles neste artigo. Para mais informações, veja Um Guia Ilustrado para Auto-Adesão SQL e Um Guia Ilustrado para o Cross Join SQL.
Vamos mergulhar mais profundamente nos primeiros quatro tipos de SQL JOIN
. Vou usar um exemplo para explicar a lógica e a sintaxe de cada tipo. Às vezes as pessoas usam diagramas Venn ao explicar os tipos de SQL JOIN. Não vou usá-los aqui, mas se isso é coisa sua, então veja o artigo Como aprender SQL JOINs
INNER JOIN
INNER JOIN
é usado para exibir os registros correspondentes de ambas as tabelas. Isto também é chamado de simples JOIN
; se você omitir a palavra-chave INNER
(ou qualquer outra palavra-chave, como LEFT
, RIGHT
, ou FULL
) e usar apenas JOIN
, este é o tipo de adesão que você obterá por padrão.
Normalmente há duas (ou mais) tabelas em uma declaração de adesão. Nós as chamamos de tabelas da esquerda e da direita. A tabela da esquerda está na cláusula FROM
- e portanto à esquerda da palavra-chave JOIN
. A tabela da direita está entre as palavras-chave JOIN
e ON
, ou à direita da palavra-chave JOIN
.
Se a condição JOIN
for atendida em um INNER JOIN
, esse registro é incluído no conjunto de dados. Pode ser de qualquer uma das tabelas. Se o registro não corresponder aos critérios, não está incluído. A imagem abaixo mostra o que aconteceria se a cor azul fosse o critério de união das tabelas da esquerda e da direita:
Vejamos como INNER JOIN
funciona em nosso exemplo. Vou fazer um simples JOIN
por conta e cliente para mostrar account
e customer
informação em uma saída:
SELECT account.*, customer. name , customer.lastname, customer.gender, customer.marital_status FROM account JOIN customer ON account.customer_id=customer.customer_id; |
Aqui está uma breve explicação do que está acontecendo:
- Estou usando
JOIN
porque estamos fundindo aaccount
ecustomer
tabelas. - O
JOIN
predicado aqui é definido por igualdade:
account.customer_id = customer.customer_id
Em outras palavras, os registros são correspondidos por valores na coluna customer_id
:
- Os registros que compartilham o mesmo valor de identificação do cliente são correspondidos. (Eles são mostrados em cores na imagem acima.) Os registros que não têm correspondência em nenhuma das tabelas (mostrados em cinza) não são incluídos no conjunto de resultados.
- Para registros que tenham uma correspondência, todos os atributos das
account
tabela são exibidas no conjunto de resultados. O nome, sobrenome, gênero e atributos de estado civil dacustomer
tabela também são exibidas.
Depois de executar este código, SQL retorna a seguir:
account_id | overdraft_amount | customer_id | type_id | segment | name | lastname | gender | marital_status |
---|---|---|---|---|---|---|---|---|
2556889 | 12000 | 4 | 2 | RET | DARIO | PENTAL | M | N |
1323598795 | 1550 | 1 | 1 | RET | MARC | TESCO | M | Y |
2225546 | 5000 | 5 | 2 | RET | ELENA | SIMSON | F | N |
5516229 | 6000 | 4 | 5 | RET | DARIO | PENTAL | M | N |
5356222 | 7500 | 5 | 5 | RET | ELENA | SIMSON | F | N |
2221889 | 5400 | 1 | 2 | RET | MARC | TESCO | M | Y |
resultado INNER JOIN
Como mencionamos anteriormente, apenas registros coloridos (combinando) foram devolvidos; todos os outros são descartados. Em termos comerciais, exibimos todas as contas de varejo com informações detalhadas sobre seus proprietários. As contas não de varejo não foram exibidas porque suas informações de clientes não são armazenadas no customer
mesa.
JOGO ESQUERDA
Às vezes você precisará manter todos os registros da mesa esquerda - mesmo que alguns não tenham um fósforo na mesa direita. No último exemplo, as fileiras cinzas não foram exibidas na saída. Essas são contas corporativas. Em alguns casos, você pode querer tê-las no conjunto de dados, mesmo que os dados de seus clientes sejam deixados vazios. Se quisermos retornar registros não emparelhados da tabela da esquerda, então devemos escrever um LEFT JOIN
. Abaixo, você pode ver que o LEFT JOIN
retorna tudo na tabela da esquerda e as linhas correspondentes na tabela da direita.
Eis como ficaria a consulta anterior se utilizássemos LEFT JOIN
ao invés de INNER JOIN
:
SELECT account.*, customer. name , customer.lastname, customer.gender, customer.marital_status FROM account LEFT JOIN customer ON account.customer_id=customer.customer_id; |
A sintaxe é idêntica. O resultado, no entanto, não é o mesmo... Agora podemos ver as contas corporativas (registros cinzas) nos resultados:
account_id | overdraft_amount | customer_id | type_id | segment | name | lastname | gender | marital_status |
---|---|---|---|---|---|---|---|---|
2556889 | 12000 | 4 | 2 | RET | DARIO | PENTAL | M | N |
1323598795 | 1550 | 1 | 1 | RET | MARC | TESCO | M | Y |
2225546 | 5000 | 5 | 2 | RET | ELENA | SIMSON | F | N |
5516229 | 6000 | 4 | 5 | RET | DARIO | PENTAL | M | N |
5356222 | 7500 | 5 | 5 | RET | ELENA | SIMSON | F | N |
2221889 | 5400 | 1 | 2 | RET | MARC | TESCO | M | Y |
2455688 | 12500 | 50 | 2 | CORP | NULL | NULL | NULL | NULL |
1322488656 | 2500 | 51 | 1 | CORP | NULL | NULL | NULL | NULL |
1323598795 | 3100 | 52 | 1 | CORP | NULL | NULL | NULL | NULL |
1323111595 | 1220 | 53 | 1 | CORP | NULL | NULL | NULL | NULL |
Left join - conta com o cliente
Observe como atributos como nome, sobrenome, sexo e estado civil nas últimas quatro linhas são preenchidos com NULLs
. Isto porque estas fileiras cinzas não têm fósforos no customer
(ou seja, customer_id
valores de 50, 51, 52 e 53 não estão presentes na tabela customer
tabela). Assim, esses atributos foram deixados NULL neste resultado.
UNIÃO DIREITA
Similar a LEFT JOIN
, RIGHT JOIN
mantém todos os registros da tabela da direita (mesmo que não haja nenhum registro correspondente na tabela da esquerda). Aqui está aquela imagem familiar para mostrar como ela funciona:
Mais uma vez, usamos o mesmo exemplo. No entanto, substituímos LEFT JOIN
por RIGHT JOIN
:
SELECT account.account_id, account.overdraft_amount, account.type_id, account.segment, account.customer_id, customer.customer_id customer. name , customer.lastname, customer.gender, customer.marital_status FROM account RIGHT JOIN customer ON account.customer_id=customer.customer_id; |
A sintaxe é quase sempre a mesma. Fiz mais uma pequena mudança: Além de account.customer_id
, adicionei também a coluna customer.customer_id
ao conjunto de resultados. Eu fiz isto para mostrar o que acontece com os registros do customer
tabela que não tem um fósforo à esquerda (account
) tabela.
Aqui está o resultado:
account_id | overdraft_amount | type_id | segment | customer_id | customer_id | name | lastname | gender | marital_status |
---|---|---|---|---|---|---|---|---|---|
1323598795 | 1550 | 1 | RET | 1 | 1 | MARC | TESCO | M | Y |
2221889 | 5400 | 2 | RET | 1 | 1 | MARC | TESCO | M | Y |
NULL | NULL | NULL | NULL | NULL | 2 | ANNA | MARTIN | F | N |
NULL | NULL | NULL | NULL | NULL | 3 | EMMA | JOHNSON | F | Y |
2556889 | 12000 | 2 | RET | 4 | 4 | DARIO | PENTAL | M | N |
5516229 | 6000 | 5 | RET | 4 | 4 | DARIO | PENTAL | M | N |
2225546 | 5000 | 2 | RET | 5 | 5 | ELENA | SIMSON | F | N |
5356222 | 7500 | 5 | RET | 5 | 5 | ELENA | SIMSON | F | N |
NULL | NULL | NULL | NULL | NULL | 6 | TIM | ROBITH | M | N |
NULL | NULL | NULL | NULL | NULL | 7 | MILA | MORRIS | F | N |
NULL | NULL | NULL | NULL | NULL | 8 | JENNY | DWARTH | F | Y |
resultado da JUNTA À DIREITA
Como você pode ver, todos os registros da tabela correta foram incluídos no conjunto de resultados. Tenha em mente:
- As identificações de clientes inigualáveis da tabela da direita (números 2,3, 6,7 e 8, mostrados em cinza) têm seus atributos de conta definidos como NULL neste conjunto de resultados. São clientes de varejo que não possuem uma conta bancária - e, portanto, nenhum registro na tabela NULL.
account
mesa. - Você pode esperar que a tabela resultante tenha oito registros porque esse é o número total de registros no
customer
mesa. No entanto, não é este o caso. Temos 11 registros porque as identificações de clientes 1, 4 e 5 têm duas contas noaccount
mesa. Todas as partidas possíveis são exibidas.
JUNÇÃO COMPLETA (EXTERNA)
Eu lhe mostrei como manter todos os registros das tabelas da esquerda ou da direita. Mas e se você quiser manter todos os registros de ambas as tabelas? Em nosso caso, você gostaria de exibir todos os registros correspondentes mais todas as contas corporativas mais todos os clientes sem contas. Para fazer isso, você pode usar FULL OUTER JOIN
. Este tipo JOIN
irá emparelhar todas as colunas correspondentes e também exibirá todas as colunas não correspondentes de ambas as tabelas. Atributos não familiares serão preenchidos com NULLs
. Dê uma olhada na imagem abaixo:
Aqui está a sintaxe FULL OUTER JOIN
:
SELECT account.*, CASE WHEN customer.customer_id IS NULL THEN account.customer_id ELSE customer.customer_id END customer_id customer. name , customer.lastname, customer.gender, customer.marital_status FROM account FULL JOIN customer |
ON account.customer_id=customer.customer_id;
Agora o resultado é o seguinte:
account_id | overdraft_amount | customer_id | type_id | segment | name | lastname | gender | marital_status |
---|---|---|---|---|---|---|---|---|
2556889 | 12000 | 4 | 2 | RET | DARIO | PENTAL | M | N |
1323598795 | 1550 | 1 | 1 | RET | MARC | TESCO | M | Y |
2225546 | 5000 | 5 | 2 | RET | ELENA | SIMSON | F | N |
5516229 | 6000 | 4 | 5 | RET | DARIO | PENTAL | M | N |
5356222 | 7500 | 5 | 5 | RET | ELENA | SIMSON | F | N |
2221889 | 5400 | 1 | 2 | RET | MARC | TESCO | M | Y |
2455688 | 12500 | 50 | 2 | CORP | NULL | NULL | NULL | NULL |
1322488656 | 2500 | 51 | 1 | CORP | NULL | NULL | NULL | NULL |
1323598795 | 3100 | 52 | 1 | CORP | NULL | NULL | NULL | NULL |
1323111595 | 1220 | 53 | 1 | CORP | NULL | NULL | NULL | NULL |
NULL | NULL | 2 | NULL | NULL | ANNA | MARTIN | F | N |
NULL | NULL | 3 | NULL | NULL | EMMA | JOHNSON | F | Y |
NULL | NULL | 6 | NULL | NULL | TIM | ROBITH | M | N |
NULL | NULL | 7 | NULL | NULL | MILA | MORRIS | F | N |
NULL | NULL | 8 | NULL | NULL | JENNY | DWARTH | F | Y |
Resultado total da união externa
Observe como as últimas cinco filas têm atributos de conta preenchidos com NULLs. Isto porque estes clientes não têm registros no account
mesa. Observe também como os clientes 50, 51, 52, e 53 têm primeiro ou último nome e outros atributos da customer
tabela preenchida com NULLs. Isto porque eles não existem na customer
mesa. Aqui, customer_id
na tabela de resultados nunca é NULL porque nós definimos customer_id
com uma declaração CASE WHEN
:
CASE WHEN customer.customer_id IS NULL THEN account.customer_id ELSE customer.customer_id END customer_id |
Isto na verdade significa que customer_id
na tabela de resultados é uma combinação de account.customer_id
e customer.customer_id
(ou seja, quando um é NULL, use o outro). Também poderíamos exibir as duas colunas na saída, mas esta declaração CASE WHEN
é mais conveniente.
Não há problema se você estiver confuso com todos os diferentes Cláusulas JOIN em SQL e com o que eles fazem. Fique com ela. Eu recomendaria que você olhasse nossa folha de trapaça SQL JOIN. Mantenha-a perto de você; ela é muito útil ao codificar. Também é útil para rever nosso artigo sobre a prática Cláusulas JOIN em SQL. Quanto mais você aprender e praticar, mais claro será Cláusulas JOIN em SQL.
Acima Próximo: Pratique Cláusulas JOIN em SQL
Neste artigo, introduzimos diferentes tipos SQL JOIN
. Dentro, à esquerda, à direita e à direita, todos retornam resultados diferentes. Agora você precisa colocar esse conhecimento em ação! Em LearnSQL.com.br Você pode encontrar mais exemplos para praticar. Nossas Consultas SQL interativas e Cláusulas JOIN em SQL Os cursos cobrem tópicos de JUNTOS, portanto, eu os encorajo a experimentá-los.