Voltar para a lista de artigos Artigos
28 minutos de leitura

As 10 principais perguntas de entrevistas sobre JOINs em SQL e como respondê-las

Você tem dúvidas de quais perguntas sobre SQL JOINs podem ser feitas em uma entrevista? Você se sente preparado para respondê-las? Este artigo cobre as perguntas mais comuns de entrevistas sobre SQL JOINs e como respondê-las.

Se você está concorrendo a uma vaga de emprego de analista de dados ou desenvolvedor de software, o seu conhecimento sobre SQL JOINs provavelmente será testado. As cláusulas JOIN em SQL são um ótimo assunto para os entrevistadores fazerem perguntas. Há muitas variações da cláusula JOIN, e cada uma executa uma tarefa diferente.

Há muitos recursos incríveis para aprender sobre as cláusulas JOIN, como o curso interativo do LearnSQL.com.br Cláusulas JOIN em SQL. Entretanto, neste artigo falaremos sobre o assunto tendo uma entrevista em mente, e cobriremos algumas das perguntas mais comuns que podem ser feitas em entrevistas sobre JOIN em SQL.

  1. O que é um comando SQL JOIN e quando precisamos usá-lo?
  2. Como você escreveria uma consulta para juntar estas duas tabelas?
  3. Que tipos de JOINs existem?
  4. O que é um SQL OUTER JOIN?
  5. Qual é a diferença entre um INNER JOIN e um LEFT JOIN em SQL?
  6. Qual é a diferença entre um LEFT JOIN e um FULL JOIN em SQL?
  7. Escreva uma consulta que juntará estas duas tabelas para que todas as linhas da Tabela 1 estejam no resultado.
  8. Como juntar mais de duas tabelas?
  9. Como unir uma tabela a ela mesma?
  10. A condição de junção deve ser de igualdade?

1. O que é um comando SQL JOIN e quando precisamos usá-lo?

O comando JOIN em SQL é usado para combinar dados de duas tabelas em SQL. A cláusula JOIN é frequentemente usada quando as tabelas têm pelo menos uma coluna de dados em comum.

Normalmente, a condição JOIN é uma igualdade entre as colunas das diferentes tabelas, mas outras condições JOIN também são possíveis. Você pode unir mais de duas tabelas usando cláusulas JOIN consecutivas.

Existem diferentes tipos de JOINs: INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN, entre outros. A função do comando JOIN é ilustrada por esta imagem:

INNER JOIN

2. Como você escreveria uma consulta para juntar estas duas tabelas?

Durante a entrevista, você poderá precisar aplicar seus conhecimentos a um cenário prático escrevendo um comando JOIN. Vejamos um exemplo para que você possa resolver este problema com facilidade.

Temos duas tabelas:

  • funcionarios - Esta tabela contém a identificação de cada funcionário, o nome e a identificação do departamento.

idnome_funcionarioid_departamento
1Homer Simpson4
2Ned Flanders1
3Barney Gumble5
4Clancy Wiggum3
5Moe SyzslakNULL
  • departamentos - Esta tabela contém a identificação e o nome de cada departamento.

id_departamentonome_departamento
1Vendas
2Engenharia
3Recursos Humanos
4Atendimento ao Cliente
5Pesquisa e Desenvolvimento

Caso você precise unir (JOIN) tabelas, tente encontrar uma coluna presente em todas as tabelas. Neste exemplo, essa coluna é a coluna id_departamento.

SELECT * 
FROM funcionarios
JOIN departamentos 
ON funcionarios.id_departamento = departamentos.id_departamento;

Ao executarmos este código, obtemos o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos

A condição ON indica como as duas tabelas (a depois de FROM e a depois de JOIN) devem ser unidas. Observe no exemplo acima que ambas as tabelas contêm a coluna id_departamento. Nossa consulta SQL retornará as linhas onde funcionarios.id_departamento corresponde a departamentos.id_departamento.

Às vezes, os campos relacionais são um pouco menos óbvios. Por exemplo, você pode ter uma tabela chamada funcionários com um campo chamado id, que poderia ser unida a id_funcionario em qualquer outra tabela.

Você também pode especificar exatamente quais colunas você gostaria de retornar de cada uma das tabelas incluídas em sua cláusula JOIN. Ao incluir um nome de coluna presente em ambas as tabelas, você deve especificar a tabela exata da qual você deseja obter a coluna em questão.

Não podemos escrever id_departamento porque isso geraria um erro de ambiguidade em SQL. Devemos escrever funcionarios.id_departamento ou departamentos.id_departamento. Como exemplo, poderíamos escrever:

SELECT 
funcionarios.id_departamento, nome_funcionario, nome_departamento
FROM funcionarios
JOIN departamentos 
ON funcionarios.id_departamento = departamentos.id_departamento;

Observe nossa declaração SELECT. Especificamos o nome exato da tabela para a coluna id_departamento porque esta coluna existe nas duas tabelas que compõem nossa cláusula JOIN. Não precisamos fazer isto para as colunas nome_funcionario ou nome_departamento porque elas são únicas. A execução desta consulta SQL gera o seguinte conjunto de resultados:

id_departamentonome_funcionarionome_departamento
1Ned FlandersVendas
3Clancy WiggumRecursos Humanos
4Homer SimpsonAtendimento ao Cliente
5Barney GumblePesquisa e Desenvolvimento

Ao escrever nossas cláusulas SQL usando JOIN, também podemos usar pseudônimos, ou apelidos (chamados de aliases, em inglês). Os nomes das colunas podem ser bastante técnicos e não muito intuitivos, o que pode tornar o resultado da consulta difícil de entender. Aqui estão algumas regras a serem seguidas ao implementar um apelido em SQL:

  • Para dar a uma coluna um nome descritivo, é possível criar um apelido para ela.
  • Para atribuir um apelido a uma coluna, use a palavra-chave AS seguida do apelido.
  • Se o apelido possuir espaços, você deve colocá-lo entre aspas simples.

Um apelido em SQL pode ser aplicado tanto aos nomes das tabelas quanto aos nomes das colunas. Se reescrevermos nossa consulta anterior para incluir um apelido para cada nome de coluna, ela ficaria assim:

SELECT 
funcionarios.id_departamento AS ID, 
nome_funcionario AS ‘Nome Funcionario’, 
nome_departamento AS Departamento
FROM funcionarios
JOIN departamentos 
ON funcionarios.id_departamento = departamentos.id_departamento;

Observe como tivemos que usar aspas simples para a nossa coluna ‘Nome Funcionario’, porque este novo nome contém espaços.

Se reescrevermos nosso código acima, desta vez usando um apelido para cada nome de tabela, obteremos o seguinte:

SELECT * 
FROM funcionarios AS fun 
JOIN departamentos AS dep 
ON fun.id_departamento = dep.id_departamento;

A palavra-chave AS usada aqui é completamente opcional, podendo ser omitida da declaração. Ao implementarmos esta pequena mudança, nosso código fica assim:

SELECT * 
FROM funcionarios fun 
JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

Esta deve ser toda a informação de que você precisa para juntar duas tabelas com uma cláusula JOIN e responder a qualquer outra pergunta que possa ser feita sobre a sintaxe básica de JOIN.

3. Que tipos de JOINs existem?

Como mencionamos na introdução deste artigo, há muitas variações para a cláusula JOIN em SQL. Demonstrar que você tem domínio de cada comando é uma forma de exibir seus conhecimentos sobre SQL JOINs. Aqui estão alguns dos tipos mais comuns de cláusulas JOIN que você encontrará:

SQL INNER JOIN

A cláusula INNER JOIN é a cláusula padrão JOIN em SQL. Considerando nosso exemplo anterior (SELECT * FROM funcionarios JOIN departamentos), o JOIN utilizado na verdade se tratou de um INNER JOIN.

INNER JOIN é utilizado para retornar linhas de ambas as tabelas que satisfaçam a condição dada. O INNER JOIN corresponde a linhas da primeira e segunda tabelas que satisfazem a condição ON.

Esta imagem demonstra a relação entre as duas tabelas incluídas em nossa cláusula INNER JOIN:

INNER JOIN

Vamos explorar melhor a sintaxe e a funcionalidade do INNER JOIN, olhando um exemplo prático usando as duas tabelas funcionarios e departamentos descritas acima.

O seguinte código SQL procura por correspondências entre as tabelas funcionarios e departamentos com base na coluna id_departamento.

SELECT * FROM funcionarios fun 
INNER JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

A execução deste código produzirá o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos

Ao observar nosso resultado, você notará que nosso funcionário Moe Szyslak não está listado. Em nossa tabela funcionarios, este funcionário não tem atualmente nenhum id_departamento. Portanto, não foi possível encontrar uma correspondência ao tentar juntar (JOIN) a tabela departamentos nesta coluna. Assim, o funcionário é excluído do resultado. Resolveremos este problema com o próximo tipo de JOIN, LEFT JOIN.

Se você quiser ver mais exemplos de INNER JOINs, este artigo com exemplos visuais e fáceis de entender pode ajudar a compreender este assunto complexo.

SQL LEFT JOIN

Semelhante à cláusula INNER JOIN, o LEFT JOIN permite que você consulte dados de duas tabelas. Mas qual é a principal diferença entre LEFT JOIN e INNER JOIN? Um LEFT JOIN retorna todas as linhas que estão na primeira tabela listada (a da esqueda). As linhas de correspondência da tabela da direita também são retornadas.

Ao usar a cláusula LEFT JOIN, introduzimos os conceitos de tabela da esquerda e tabela da direita.

LEFT JOIN

No diagrama acima, a Tabela 1 é a tabela da esquerda, e a Tabela 2 é a tabela da direita.

A cláusula LEFT JOIN seleciona dados a partir da tabela da esquerda. Ela combina cada linha da tabela da esquerda com linhas da tabela da direita, com base na condição da cláusula JOIN.

A cláusula SQL LEFT JOIN retorna todas as linhas da tabela da esquerda, mesmo se não houver correspondências na tabela da direita. Isto significa que se a cláusula ON não corresponder a nenhum registro na tabela da direita, a cláusula JOIN ainda retornará uma linha no resultado, exibindo um NULL (correspondente a um valor vazio) em cada coluna da tabela da direita.

Em SQL, o LEFT JOIN retorna todos os valores da tabela da esquerda, mais os valores correspondentes da tabela da direita. Se não for possível encontrar uma correspondência, o LEFT JOIN retornará um valor NULL.

A sintaxe da nossa cláusula SQL usando LEFT JOIN é a seguinte:

SELECT * FROM funcionarios fun 
LEFT JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

Especificamos que queremos um LEFT JOIN. Isso se repetirá para todos os tipos de JOIN. Especifique qual variante do JOIN você está usando antes da palavra-chave JOIN.

A palavra-chave ON funciona da mesma forma que no nosso exemplo com INNER JOIN. Estamos procurando por valores correspondentes entre a coluna id_departamento da nossa tabela de funcionarios e a coluna id_departamento da nossa tabela departamentos.

Aqui, nossa tabela funcionarios funcionará como a tabela da esquerda, já que ela foi a primeira tabela que especificamos.

Ao executarmos esta consulta em SQL, obtemos o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL

Observe como o nosso funcionário, Moe Szyslak, foi incluído no conjunto de resultados, apesar de não haver uma correspondência em id_departamento na tabela departamentos. Este é exatamente o objetivo da cláusula LEFT JOIN: incluir todos os dados da nossa tabela da esquerda, independentemente de terem sido encontrados ou não.

SQL RIGHT JOIN

RIGHT JOIN é semelhante a LEFT JOIN, exceto pelo fato de que a ação realizada nas tabelas unidas é invertida. Essencialmente, ela executa a ação oposta de LEFT JOIN. Isto significa que um RIGHT JOIN retorna todos os valores da tabela da direita, mais os valores correspondentes da tabela da esquerda ou NULL, no caso de não haver correspondência no JOIN.

No diagrama abaixo, a Tabela 2 é a tabela da direita e a Tabela 1 é a tabela da esquerda:

RIGHT JOIN

Quando aplicamos o seguinte código às tabelas funcionarios e departamentos, obtemos:

SELECT * FROM funcionarios fun 
RIGHT JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

A sintaxe é semelhante à do LEFT JOIN. Especificamos que queremos realizar um RIGHT JOIN, procurando especificamente as combinações entre a tabela departamentos e a tabela funcionarios.

Aqui, nossa tabela funcionarios funcionará como a tabela da esquerda, já que esta foi a primeira tabela que especificamos. A tabela departamentos será a tabela da direita. O resultado da execução desta consulta SQL JOIN seria o seguinte:

idnome_funcionarioid_departamentoid_departamentonome_departamento
2Ned Flanders11Vendas
NULLNULLNULL2Engenharia
4Clancy Wiggum33Recursos Humanos
1Homer Simpson44Atendimento ao Cliente
3Barney Gumble55Pesquisa e Desenvolvimento

O RIGHT JOIN começa a selecionar os dados da tabela da direita (departamentos), combinando cada linha da tabela da direita com cada linha da tabela da esquerda. Se ambas as linhas fizerem com que a condição JOIN seja verdadeira, ela combina as colunas em uma nova linha e inclui esta nova linha no conjunto de resultados.

SQL FULL JOIN

Em SQL, a cláusula FULL JOIN combina os resultados dos dois OUTER JOINs (RIGHT JOIN e LEFT JOIN). A tabela unida conterá todos os registros de ambas as tabelas e incluirá valores NULL para casos em que não houve correspondência entre os dois lados.

Esteja ciente de que um FULL JOIN pode retornar um conjunto de dados muito grande. Um FULL JOIN retorna todas as linhas das tabelas unidas, independente de haver ou não correspondência.

O SQL FULL JOIN é um tipo de OUTER JOIN (veremos isso mais adiante no artigo) e é por isso que também pode ser chamado de FULL OUTER JOIN.

Aqui está o conceito de um SQL FULL JOIN claramente ilustrado:

FULL JOIN

Observe que no nosso diagrama todas as linhas das duas tabelas é retornada.

Vejamos a sintaxe da cláusula FULL JOIN em SQL através de um exemplo.

SELECT * FROM funcionarios fun 
FULL JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

Ao executarmos esta consulta SQL com as nossas tabelas, funcionarios e departamentos, obtemos o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL
2Ned Flanders11Vendas
NULLNULL2Engenharia
4Clancy Wiggum33Recursos Humanos
1Homer Simpson44Atendimento ao Cliente
3Barney Gumble55Pesquisa e Desenvolvimento

Compare este conjunto de resultados com os resultados do nosso LEFT JOIN e RIGHT JOIN. Você verá que estes dados são uma combinação dos dados retornados a partir de nossos exemplos anteriores. Este tipo específico de cláusula JOIN produz um conjunto de dados grande. Pense bem antes de usar a cláusula FULL JOIN.

CROSS JOIN

Em SQL, usamos o CROSS JOIN quando precisamos descobrir todas as possibilidades de combinações entre duas tabelas, onde o conjunto de resultados inclui cada linha de cada tabela contribuinte. A cláusula CROSS JOIN retorna o produto cartesiano de linhas das tabelas unidas.

O diagrama abaixo é uma boa ilustração de como as linhas são combinadas:

CROSS JOIN

O CROSS JOIN produz um conjunto de resultados cujo tamanho é o número de linhas na primeira tabela multiplicado pelo número de linhas na segunda tabela. Este tipo de resultado é chamado de Produto Cartesiano de duas tabelas (Tabela 1 x Tabela 2).

Vejamos as duas tabelas que usamos anteriormente:

  • Tabela funcionarios
idnome_funcionarioid_departamento
1Homer Simpson4
2Ned Flanders1
3Barney Gumble5
4Clancy Wiggum3
5Moe SyzslakNULL
  • Tabela departamentos
id_departamentonome_departamento
1Vendas
2Engenharia
3Recursos Humanos
4Atendimento ao Cliente
5Pesquisa e Desenvolvimento

Para realizar um CROSS JOIN usando estas tabelas, poderíamos escrever a seguinte consulta em SQL:

SELECT * FROM funcionarios
CROSS JOIN departamentos;

Observe como o CROSS JOIN não usa ON ou USING quando está sendo declarado, diferente do que ocorre com as cláusulas JOIN que vimos anteriormente.

Ao executar um CROSS JOIN, o conjunto de resultados seria o seguinte:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson41Vendas
2Ned Flanders11Vendas
3Barney Gumble51Vendas
4Clancy Wiggum31Vendas
5Moe SzyslakNULL1Vendas
1Homer Simpson42Engenharia
2Ned Flanders12Engenharia
3Barney Gumble52Engenharia
4Clancy Wiggum32Engenharia
5Moe SzyslakNULL2Engenharia
1Homer Simpson43Recursos Humanos
2Ned Flanders13Recursos Humanos
3Barney Gumble53Recursos Humanos
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULL3Recursos Humanos
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders14Atendimento ao Cliente
3Barney Gumble54Atendimento ao Cliente
4Clancy Wiggum34Atendimento ao Cliente
5Moe SzyslakNULL4Atendimento ao Cliente
1Homer Simpson45Pesquisa e Desenvolvimento
2Ned Flanders15Pesquisa e Desenvolvimento
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum35Pesquisa e Desenvolvimento
5Moe SzyslakNULL5Pesquisa e Desenvolvimento

Nosso conjunto de resultados contém todas as combinações possíveis entre as duas tabelas. Mesmo quando as tabelas utilizadas têm poucos dados, como é o caso das nossas tabelas de funcionarios e departamentos, o conjunto de resultados gerado pode ser enorme ao usarmos uma cláusula CROSS JOIN.

SQL NATURAL JOIN

O NATURAL JOIN é um tipo de JOIN que combina tabelas com base em colunas com o mesmo nome e tipo de dados. Quando você usa a cláusula NATURAL JOIN, ela cria uma cláusula JOIN implícita com base nas colunas comuns nas duas tabelas que estão sendo unidas.

Colunas comuns são colunas que têm o mesmo nome em ambas as tabelas. Não há necessidade de especificar os nomes das colunas a serem unidas. A tabela resultante não conterá nenhuma coluna repetida.

A sintaxe de uma NATURAL JOIN é simples:

SELECT * FROM funcionarios
NATURAL JOIN departamentos;

Quando esta consulta for executada, ela produzirá o seguinte conjunto de resultados:

id_departamentoidnome_funcionarionome_departamento
12Ned FlandersVendas
34Clancy WiggumRecursos Humanos
41Homer SimpsonAtendimento ao Cliente
53Barney GumblePesquisa e Desenvolvimento

O NATURAL JOIN é executado na coluna compartilhada entre as duas tabelas. Neste caso, seria a coluna id_departamento. Esta coluna correspondente é exibida apenas uma vez em nosso conjunto de resultados.

4. O que é um SQL OUTER JOIN?

Com um SQL OUTER JOIN, linhas sem correspondências em uma ou ambas as tabelas podem ser retornadas. Existem diversas variações da cláusula OUTER JOIN, algumas das quais já abordamos neste artigo. Aqui estão os tipos comuns de cláusulas OUTER JOIN:

  • LEFT OUTER JOIN
  • RIGHT OUTER JOIN
  • FULL OUTER JOIN

LEFT JOIN é um sinônimo de LEFT OUTER JOIN, e ambas funcionam exatamente da mesma forma. Esta pode ser uma das perguntas sobre JOINs que podem ser feitas em uma entrevista! O mesmo pode ser dito para RIGHT JOIN e RIGHT OUTER JOIN e para FULL JOIN e FULL OUTER JOIN. Vejamos um exemplo para cada uma delas.

SQL LEFT OUTER JOIN

Use um LEFT OUTER JOIN quando quiser todos os resultados que estão na primeira tabela listada. Um LEFT OUTER JOIN retornará somente as linhas correspondentes da segunda tabela.

A sintaxe para a cláusula LEFT OUTER JOIN é a seguinte:

SELECT * FROM funcionarios fun 
LEFT OUTER JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

O resultado da execução desta consulta SQL seria o seguinte conjunto de resultados:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL

Observe que o nosso funcionário Moe Syzslak foi incluído no conjunto de resultados mesmo não havendo um id_departamento correspondente na tabela departamentos. Este é exatamente o objetivo da cláusula LEFT OUTER JOIN: incluir todos os dados de nossa tabela da esquerda, independentemente de terem sido encontradas correspondências ou não.

SQL RIGHT OUTER JOIN

RIGHT OUTER JOIN é semelhante a LEFT OUTER JOIN, exceto que a ação realizada nas tabelas unidas é invertida. Essencialmente, ele executa a ação oposta da cláusula LEFT OUTER JOIN, ou seja, retorna todos os valores da tabela da direita, mais os valores correspondentes da tabela esquerda ou NULL, no caso de não haver correspondência.

Quando aplicamos o RIGHT OUTER JOIN à nossa tabela funcionarios e à nossa tabela departamentos, o código fica assim:

SELECT * FROM funcionarios fun 
RIGHT OUTER JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

Aqui, nossa tabela funcionarios funcionará como a tabela da esquerda por ter sido a primeira tabela que especificamos.

Ao executar esta consulta em SQL, o conjunto de resultados seria o seguinte:

idnome_funcionarioid_departamentoid_departamentonome_departamento
2Ned Flanders11Vendas
NULLNULLNULL2Engenharia
4Clancy Wiggum33Recursos Humanos
1Homer Simpson44Atendimento ao Cliente
3Barney Gumble55Pesquisa e Desenvolvimento

RIGHT OUTER JOIN começa a selecionar os dados da tabela da direita, que neste caso seria a nossa tabela departamentos, combinando cada linha da tabela da direita com cada linha da tabela da esquerda. Se ambas as linhas fizerem com que a condição JOIN seja verdadeira, ela combina as colunas em uma nova linha e inclui esta nova linha no conjunto de resultados.

SQL FULL OUTER JOIN

Em SQL, o FULL OUTER JOIN combina os resultados das duas OUTER JOINs (LEFT e RIGHT). A tabela unida contém todos os registros de ambas as tabelas e inclui NULLs quando não há correspondência entre os dois lados. O FULL OUTER JOIN retorna todas as linhas das tabelas unidas, independente de haver correspondência entre elas ou não.

Vejamos a sintaxe da cláusula FULL OUTER JOIN em SQL:

SELECT * FROM funcionarios fuh 
FULL OUTER JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

Quando esta consulta SQL é executada com as tabelas funcionarios e departamentos, ela produz o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL
2Ned Flanders11Vendas
NULLNULL2Engenharia
4Clancy Wiggum33Recursos Humanos
1Homer Simpson44Atendimento ao Cliente
3Barney Gumble55Pesquisa e Desenvolvimento

Você notará que este conjunto de dados é uma combinação de nossas consultas anteriores usando LEFT OUTER JOIN e RIGHT OUTER JOIN.

5. Qual é a diferença entre um INNER JOIN e um LEFT JOIN em SQL?

Há algumas diferenças importantes a serem lembradas sobre estes dois tipos JOIN muito comuns. INNER JOIN retorna linhas quando há uma correspondência nas duas tabelas. LEFT JOIN retorna todas as linhas da tabela da esquerda e quaisquer linhas correspondentes da tabela da direita.

Vamos conferir um exemplo prático para explorar as diferenças entre estas cláusulas, para que você possa responder com confiança a esta pergunta comum em entrevistas sobre JOINs em SQL.

Imagine que temos duas tabelas:

  • funcionarios - Esta tabela contém a identificação de cada funcionário, o nome e a identificação do departamento.
idnome_funcionarioid_departamento
1Homer Simpson4
2Ned Flanders1
3Barney Gumble5
4Clancy Wiggum3
5Moe SyzslakNULL
  • departamentos - Esta tabela contém a identificação e o nome de cada departamento.
id_departamentonome_departamento
1Vendas
2Engenharia
3Recursos Humanos
4Atendimento ao Cliente
5Pesquisa e Desenvolvimento

O seguinte código SQL procura correspondências entre as tabelas funcionarios e departamentos com base na coluna id_departamento:

SELECT * from funcionarios fun 
INNER JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

A execução deste código produzirá o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos

Ao olhar para o resultado, você notará que nosso funcionário Moe Szyslak está faltando. Em nossa tabela funcionarios, este funcionário atualmente não possui um id_departamento. Portanto, não foi possível encontrar uma correspondência ao juntar a tabela departamentos com base nesta coluna. Assim, o funcionário é excluído do resultado.

Agora, vamos usar um LEFT JOIN e ver o resultado gerado. Um SQL LEFT JOIN retorna todos os valores da tabela da esquerda, mais os valores correspondentes da tabela da direita. Se não for possível encontrar uma correspondência, LEFT JOIN retorna um valor NULL.

A sintaxe de nossa cláusulaLEFT JOIN é a seguinte:

SELECT * FROM funcionarios fun
LEFT JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

A palavra-chave ON funciona da mesma forma que no exemplo INNER JOIN. Estamos procurando por valores correspondentes entre a coluna id_departamento da nossa tabela funcionarios e a coluna id_departamento da nossa tabela departamentos.

Aqui, nossa tabela funcionarios funcionará como a tabela da esquerda por ter sido a primeira tabela que especificamos.

Ao executarmos esta consulta SQL obtemos o seguinte conjunto de resultados:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL

Observe que Moe Szyslak foi incluído neste conjunto de resultados, apesar de não haver uma correspondência com a coluna id_departamento na tabela departamentos. Este é exatamente o objetivo da cláusula LEFT JOIN: incluir todos os dados da nossa tabela da esquerda, independentemente de terem sido encontrados ou não.

6. Qual é a diferença entre um LEFT JOIN e um FULL JOIN em SQL?

Esta é uma das perguntas sobre JOINs em SQL que podem ser feitas durante entrevistas.

Como mencionamos anteriormente, um LEFT JOIN em SQL retorna todos os valores da tabela da esquerda, mais os valores correspondentes da tabela da direita. Se não for encontrada nenhuma correspondência, LEFT JOIN retorna um valor NULL. Um FULL JOIN em SQL retorna todas as linhas das tabelas unidas, independente de haver correspondência entre elas. Na prática, ele combina o funcionamento de um LEFT JOIN e de um RIGHT JOIN.

Vamos comparar o conjunto de resultados de uma cláusula LEFT JOIN com o conjunto de resultados de uma cláusula FULL JOIN.

Abaixo está uma consulta utilizando LEFT JOIN:

SELECT * FROM funcionarios fun 
LEFT JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

Aqui, nossa tabela funcionarios funcionará como a tabela da esquerda por ter sido a primeira tabela que especificamos.

O resultado da execução desta consulta SQL é:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL

Compare este resultado ao resultado gerado com o uso do FULL JOIN. A sintaxe é semelhante, como podemos ver neste código:

SELECT * FROM funcionarios fun 
FULL JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

Quando esta consulta SQL é executada com as nossas tabelas funcionarios e departamentos, ele produz o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL
NULLNULLNULL2Engenharia

Compare este conjunto de resultados com os resultados de nossas consultas LEFT JOIN e RIGHT JOIN. Você pode ver que não foi encontrada nenhuma correspondência para o departamento de engenharia, mas ainda assim ele foi exibido. Fica claro que estes dados são uma combinação dos dados retornados a partir de nossos exemplos anteriores. Este tipo específico de cláusula JOIN produz um enorme conjunto de dados. Pense bem antes de usar um SQL FULL JOIN.

7. Escreva uma consulta que juntará estas duas tabelas para que todas as linhas da Tabela 1 estejam no resultado.

Em uma entrevista para o cargo de analista de dados ou desenvolvedor de software, você poderá precisar realizar um desafio técnico envolvendo SQL. Um desafio comum de entrevistas usando SQL JOINs é escrever uma consulta para juntar duas tabelas de uma forma específica. Vamos supor que você precisa escrever uma consulta para unir duas tabelas de forma que todas as linhas da Tabela 1 sejam exibidas no resultado.

Primeiro, você deve entender o conceito de tabelas da direita e da esquerda.

LEFT JOIN

No diagrama acima, a Tabela 1 é a tabela da esquerda e a Tabela 2 é a tabela da direita. Em outras palavras, a tabela da esquerda vem em primeiro lugar na consulta; essa identificação resulta do fato de ela estar à esquerda da condição de união (JOIN). A tabela da direita vem após a palavra-chave JOIN.

A cláusula LEFT JOIN seleciona os dados a partir da tabela da esquerda. Ela combina cada linha da tabela da esquerda com linhas da tabela da direita, com base na condição da cláusula JOIN. Ela retorna todos os valores da tabela da esquerda, mais os valores correspondentes da tabela da direita. Se não for encontrada nenhuma correspondência, LEFT JOIN retorna um valor NULL. Isto significa que se a cláusula ON não corresponder a nenhum registro da tabela da direita, o JOIN ainda retornará essa linha, mas com um valor NULL em cada coluna da tabela da direita.

Como exemplo prático, utilizaremos as tabelas funcionarios e departamentos do nosso exemplo anterior:

funcionarios - Esta tabela contém a identificação de cada funcionário, o nome e a identificação do departamento.

idnome_funcionarioid_departamento
1Homer Simpson4
2Ned Flanders1
3Barney Gumble5
4Clancy Wiggum3
5Moe SyzslakNULL

departamentos - Esta tabela contém a identificação e o nome de cada departamento.

id_departamentonome_departamento
1Vendas
2Engenharia
3Recursos Humanos
4Atendimento ao Cliente
5Pesquisa e Desenvolvimento

Se quisermos manter todas as linhas da Tabela 1 (neste caso, funcionarios) devemos especificar que ela representa a nossa tabela da esquerda.

A sintaxe para esta cláusula LEFT JOIN é a seguinte:

SELECT * FROM funcionarios fun 
LEFT JOIN departamentos dep 
ON fun.id_departamento = dep.id_departamento;

A execução desta consulta gera o seguinte resultado:

idnome_funcionarioid_departamentoid_departamentonome_departamento
1Homer Simpson44Atendimento ao Cliente
2Ned Flanders11Vendas
3Barney Gumble55Pesquisa e Desenvolvimento
4Clancy Wiggum33Recursos Humanos
5Moe SzyslakNULLNULLNULL

Observe que o funcionário Moe Szyslak foi incluído neste conjunto de resultados, mesmo sem haver uma correspondência com a coluna id_departamento na tabela departamentos. Este é exatamente o objetivo da cláusula LEFT JOIN: incluir todos os dados de nossa tabela da esquerda, independentemente de terem sido encontradas correspondências ou não com a tabela da direita.

8. Como juntar mais de duas tabelas?

Para os recém-chegados no mundo de SQL, juntar mais de duas tabelas em uma única consulta SQL pode ser uma tarefa bem difícil. O exemplo a seguir deve esclarecer um pouco o processo.

Você executa um JOIN em mais de duas tabelas quando os dados que você deseja incluir no resultado existem em três ou mais tabelas. Uma junção de várias tabelas requer o uso de JOIN consecutivas: primeiro, você junta a primeira e a segunda tabela e obtém um conjunto de resultados virtual. Depois, você junta a outra tabela a esta tabela virtual. Vamos ver um exemplo.

Para o nosso exemplo de junção múltipla, vamos imaginar que temos três tabelas:

departamentos - Esta tabela contém a identificação e o nome de cada departamento.

id_departamentonome_departamento
1Vendas
2Engenharia
3Recursos Humanos
4Atendimento ao Cliente
5Pesquisa e Desenvolvimento

escritorio - Esta tabela contém o endereço de cada escritório.

idendereco
15 Wisteria Lane, Springfield, USA
2124 Chestmount Street, Springfield, USA
36610 Bronzeway, Springfield, USA
4532 Executive Lane, Springfield, USA
510 Meadow View, Springfield, USA

departamento_escritorio - Esta tabela une as informações do escritório ao departamento associado. Alguns departamentos podem incluir vários escritórios.

id_escritorioid_departamento
11
23
32
44
55
21
51
43

No nosso caso, usamos uma tabela de links chamada departamento_escritorio que liga ou relaciona os departamentos aos escritórios.

Para escrever uma consulta SQL que mostre os atributos nome_departamento e endereco lado a lado, precisamos unir três tabelas:

  • A primeira cláusula JOIN unirá as tabelas departamentos e departamento_escritorio, criando uma tabela temporária composta por uma coluna id_escritorio.
  • A segunda declaração JOIN juntará esta tabela temporária com a tabela escritorio em id_escritorio para obter o resultado desejado.

Confira a consulta SQL abaixo:

SELECT nome_departamento, endereco
FROM departamentos d 
JOIN departamento_escritorio de ON d.id_departamento=de.id_departamento 
JOIN escritorio e ON de.id_escritorio=e.id;

Perceba que só queremos recuperar duas colunas: o nome do departamento e o endereço associado. Nós juntamos a tabela departamento_escritorio, que tem um link para as tabelas departamentos e escritorio. Com isso, conseguimos juntar a tabela escritorio que contém a coluna endereco em nossa declaração SELECT.

A execução deste código produz o seguinte resultado:

nome_departamentoendereco
Vendas5 Wisteria Lane, Springfield, USA
Engenharia124 Chestmount Street, Springfield, USA
Recursos Humanos6610 Bronzeway, Springfield, USA
Atendimento ao Cliente532 Executive Lane, Springfield, USA
Pesquisa e Desenvolvimento10 Meadow View, Springfield, USA
Vendas124 Chestmount Street, Springfield, USA
Vendas10 Meadow View, Springfield, USA
Recursos Humanos532 Executive Lane, Springfield, USA

Aí está! Chegamos ao resultado desejado: cada departamento e seu respectivo endereço. Observe que o departamento de vendas é o maior de todos, abrangendo três escritórios diferentes. O segundo maior departamento é o de recursos humanos, que engloba dois escritórios diferentes.

Você pode ver como as cláusulas JOIN podem ser usadas em várias tabelas para criar links entre tabelas com colunas em comum. Existem várias situações diferentes em que pode ser útil unir várias tabelas; para mais informações, veja este artigo sobre como juntar três ou mais tabelas em SQL.

9. Como unir uma tabela a ela mesma?

Muitos iniciantes não sabem, mas é possível unir uma tabela a ela mesma. Tal operação é comumente chamada de Self Join (auto-junção, ou autounião). Ela é útil para consultar dados hierárquicos ou comparar linhas dentro de uma mesma tabela. Ao utilizar um Self Join, é importante usar um pseudônimo (apelido) para cada tabela.

Para nosso exemplo de Self Join, usaremos a seguinte tabela:

funcionario - Esta tabela armazena os nomes de todos os funcionários da empresa, os IDs de seus departamentos e os IDs de seus gerentes.

idnome_funcionarioid_departamentoid_gerente
1Montgomery Burns4NULL
2Waylon Smithers11
3Homer Simpson21
4Carl Carlson51
5Lenny Leonard31
6Frank Grimes23

Vamos supor que queremos um conjunto de resultados que mostre apenas funcionários e seus respectivos gerentes. Isto pode ser feito facilmente usando um apelido de tabela em combinação com um Self Join. Usaremos um SQL LEFT JOIN para o nosso primeiro Self Join. Veja o código abaixo:

SELECT 
f.nome_funcionario AS 'funcionario',
g.nome_funcionario AS 'gerente'
FROM funcionario f
LEFT JOIN funcionario g ON g.id = f.id_gerente

Cuidado com o erro de colunas ambíguas, que pode facilmente acontecer se você não tiver cuidado ao escrever uma consulta de auto-junção. Para evitar este erro, faça bom uso dos apelidos em SQL - ou seja, especifique um apelido para cada ocorrência da tabela em sua consulta SQL. Na consulta acima, isso é visto no seguinte trecho:

FROM funcionario f LEFT JOIN funcionario g

Você também deve prefixar os nomes das colunas com o apelido da tabela para esclarecer a qual tabela cada coluna pertence. No exemplo acima, especificamos explicitamente f.nome_funcionario e g.nome_funcionario.

Estas regras o ajudarão a executar com sucesso uma consulta SQL usando Self Join, evitando o erro de colunas ambíguas.

A execução da consulta acima produz o seguinte conjunto de resultados:

funcionariogerente
Montgomery BurnsNULL
Waylon SmithersMontgomery Burns
Homer SimpsonMontgomery Burns
Carl CarlsonMontgomery Burns
Lenny LeonardMontgomery Burns
Frank GrimesHomer Simpson

Eis o resultado que esperávamos! Conseguimos identificar claramente cada par de funcionário e seu respectivo gerente. A maioria dos funcionários se reporta ao Sr. Burns, embora o gerente de Frank Grimes seja Homer Simpson. Observe o valor NULL sob a coluna Gerente para Montgomery Burns. Isto ocorre porque Montgomery Burns não tem gerente - ele é o chefe.

Vamos ajustar um pouco a consulta e usar um INNER JOIN desta vez:

SELECT 
f.nome_funcionario AS 'funcionario',
g.nome_funcionario AS 'gerente'
FROM funcionario f
INNER JOIN tbl_funcionario g ON g.id = f.id_gerente
funcionariogerente
Waylon SmithersMontgomery Burns
Homer SimpsonMontgomery Burns
Carl CarlsonMontgomery Burns
Lenny LeonardMontgomery Burns
Frank GrimesHomer Simpson

A única grande diferença aqui é a ausência de Montgomery Burns na coluna funcionário. Isto ocorre porque o valor id_gerente para ele era NULL; INNER JOIN retorna apenas colunas correspondentes, excluindo os valores NULL.

Agora você pode realizar auto-junções, que são aplicáveis em muitos casos para diferentes usos. Se você quiser ver mais exemplos de auto-junção, confira este excelente guia ilustrado sobre Self Joins (auto-junção).

10. A condição de junção deve ser de igualdade?

Um JOIN não-equi é qualquer cláusula JOIN que não utilize a igualdade ( = ) como condição de junção. Você pode utilizar operadores comuns de comparação (por exemplo, <, >, <=, >=, != e <>) em conjunto com as cláusulas JOIN. O operador BETWEEN também pode ser usado.

Há muitas situações em que JOINs não-equi (sem igualdade) podem ser úteis, incluindo a listagem de pares únicos, a listagem de registros dentro de um intervalo e a identificação de duplicatas. Vejamos nosso último exemplo: como identificar duplicatas usando um JOIN não-equi.

Primeiro, veja os dados que estaremos consultando. Neste exemplo usaremos apenas uma tabela, a tabela funcionario, que já conhecemos bem:

idnome_funcionarioid_departamentoid_gerente
1Montgomery Burns4NULL
2Waylon Smithers11
3Homer Simpson21
4Carl Carlson51
5Lenny Leonard31
6Frank Grimes23
7Lenny Leonard31

Se quiséssemos identificar rapidamente quaisquer valores duplicados, escreveríamos a seguinte consulta, que faz bom uso de uma junção não-equi:

SELECT f1.id, f1.nome_funcionario, f2.id, f2.nome_funcionario
FROM funcionario f1
JOIN funcionario f2
ON f1.nome_funcionario = f2.nome_funcionario AND f1.id < f2.id

Dando uma olhada mais de perto na cláusula JOIN, podemos ver que ela tem duas condições:

  1. Ela faz correspondências entre registros que têm o mesmo nome.
  2. Ela recupera registros onde o ID é menor do que o ID da tabela temporária de auto-junção.

A execução desta consulta produz o seguinte conjunto de resultados:

idnome_funcionarioidnome_funcionario
5Lenny Leonard7Lenny Leonard

Podemos ver que Lenny Leonard tem um registro duplicado nesta tabela. As duplicatas podem causar erros imprevisíveis e atrapalhar o uso dos dados em seus relatórios.

Este foi apenas um dos muitos exemplos possíveis que demonstram a utilidade dos JOINs sem igualdade. Há outros excelentes recursos disponíveis on-line, como este artigo que mostra as aplicações práticas dos JOINs não-equis.

As 10 perguntas mais importantes de um entrevista SQL respondidas

Agora você está equipado com os conhecimentos necessários para responder a perguntas complexas de entrevistas sobre SQL JOIN. Se você ainda se sente sobrecarregado ou inseguro sobre o uso das cláusulas SQL JOIN, aqui está um excelente conselho sobre a melhor abordagem para praticar as cláusulas SQL JOIN.

Você pode usar isto em combinação com a folha de consultas SQL JOIN, que funciona como uma grande ferramenta de referência tanto para programadores SQL novos quanto para programadores SQL experientes. Se você é novo em SQL ou sente que precisa atualizar seus conhecimentos sobre o assunto, este curso interativo Cláusulas JOIN em SQL pode ser um maravilhoso recurso de aprendizado.