Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2024
Banco de Dados›Consultas e Comandos em SQL
Código
fg165276
Banca
FGV
Órgão
Pref Nova Iguaçu
Ano
2024
Cargo
ATTM ( )
Seja um banco de dados relacional especificado em SQL de uma empresa de correspondência entre clientes, instituições financeiras e empréstimos contratados por esses clientes nessas instituições, previamente implementado em um banco de dados como a seguir:
create table tb_cliente ( id_cliente integer primary key, num_cpf char(11) unique, nome varchar(50) not null, email varchar(20), telefone varchar(20), endereco varchar(100), cidade varchar(20), estado char(2) );
create table tb_financeira ( id_financeira integer primary key, razao_social varchar(30) not null, cidade varchar(30) not null, estado char(2) not null );
create table tb_emprestimo ( id_financeira integer references tb_financeira, id_cliente integer references tb_cliente, valor real not null check(valor > 0), dia integer not null check(dia >= 1 and dia <= 31), mes integer not null check(mes >= 1 and mes <= 12), ano integer not null check(ano >= 1980 and ano <= 2100), primary key(id_financeira, id_cliente, dia, mes, ano) );
OBS: Neste banco de dados, cadeias de caracteres (strings) são representadas envoltas em aspas simples.
Para que a consulta a seguir reflita o resultado dos clientes cadastrados que não contrataram empréstimos, qual a opção que corretamente substitui o trecho na cláusula from do comando SQL, padrão ANSI, destacado como /* TERMO */ ?
select c.nome
from tb_emprestimo e /* TERMO */ join tb_cliente c
on c.id_cliente = e.id_cliente
where e.id_financeira is null
Ainner
Bleft
Cnatural
Douter
Eright
Revelar gabarito e comentário▾
GabaritoE — right
Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.
Junções SQL: LEFT, RIGHT e INNER JOIN
Gabarito: letra E. Para listar os clientes cadastrados que não contrataram empréstimos, a consulta precisa partir da tabela tb_cliente (todos os clientes) e trazer os empréstimos correspondentes, preservando os clientes sem empréstimo — exatamente o que o RIGHT JOIN faz quando tb_cliente está do lado direito da junção. A condição WHERE e.id_financeira IS NULL filtra justamente os registros em que não houve correspondência, ou seja, os clientes sem empréstimo.
O comando SELECT apresentado na questão usa a sintaxe FROM tb_emprestimo e /* TERMO */ JOIN tb_cliente c. O /* TERMO */ é um comentário que deve ser substituído pelo tipo de junção. Para entender qual tipo usar, precisamos lembrar o que cada junção faz:
INNER JOIN: retorna apenas as linhas que têm correspondência nas duas tabelas. Clientes sem empréstimo seriam descartados.
LEFT JOIN: retorna todas as linhas da tabela à esquerda (no caso, tb_emprestimo) e as correspondências da tabela à direita (tb_cliente). Como a tabela à esquerda é tb_emprestimo, todos os empréstimos apareceriam, mas clientes sem empréstimo não apareceriam.
RIGHT JOIN: retorna todas as linhas da tabela à direita (no caso, tb_cliente) e as correspondências da tabela à esquerda (tb_emprestimo). Assim, todos os clientes aparecem, inclusive os que não têm empréstimo.
FULL OUTER JOIN: retorna todas as linhas de ambas as tabelas, com NULL onde não há correspondência.
NATURAL JOIN: faz uma junção automática pelas colunas com o mesmo nome, o que não é o caso aqui (as colunas de junção têm nomes diferentes: id_cliente em ambas, mas a sintaxe usa ON).
A consulta quer os clientes que não contrataram empréstimos. Isso significa que precisamos de todos os clientes, mesmo aqueles sem empréstimo. A tabela tb_cliente está à direita na junção. Portanto, precisamos de um RIGHT JOIN para preservar todos os clientes.
Vamos ver o que acontece com cada tipo de junção:
Tipo de Junção
Tabela preservada
Clientes sem empréstimo aparecem?
INNER
Nenhuma
Não
LEFT
tb_emprestimo (esquerda)
Não
RIGHT
tb_cliente (direita)
Sim
FULL OUTER
Ambas
Sim
NATURAL
Automática
Depende
A condição WHERE e.id_financeira IS NULL só será verdadeira para linhas em que não houve correspondência na tabela tb_emprestimo. Isso só acontece com RIGHT JOIN (ou FULL OUTER JOIN, mas não é uma opção). Portanto, a alternativa correta é a letra E.
Tipos de JOIN: INNER (só correspondências nas duas); LEFT (preserva tabela da esquerda); RIGHT (preserva tabela da direita); FULL OUTER (preserva ambas); NATURAL (junção automática por colunas iguais)
Alternativa A — ❌ Incorreta
O INNER JOIN retorna apenas as linhas com correspondência nas duas tabelas. Clientes sem empréstimo seriam excluídos do resultado, e a condição WHERE e.id_financeira IS NULL nunca seria verdadeira, pois id_financeira nunca seria NULL em um INNER JOIN.
Alternativa B — ❌ Incorreta
O LEFT JOIN preserva todas as linhas da tabela à esquerda (tb_emprestimo). Como a tabela à esquerda é tb_emprestimo, todos os empréstimos apareceriam, mas clientes sem empréstimo não apareceriam, pois não há linha correspondente em tb_emprestimo para eles. A condição WHERE e.id_financeira IS NULL nunca seria verdadeira.
Alternativa C — ❌ Incorreta
O NATURAL JOIN faz uma junção automática pelas colunas com o mesmo nome. No entanto, a sintaxe da consulta usa ON c.id_cliente = e.id_cliente, o que é incompatível com NATURAL JOIN. Além disso, mesmo que funcionasse, o NATURAL JOIN é um INNER JOIN, que descartaria clientes sem empréstimo.
Alternativa D — ❌ Incorreta
OUTER não é um tipo de junção válido por si só. As junções externas são LEFT OUTER JOIN, RIGHT OUTER JOIN e FULL OUTER JOIN. A palavra OUTER é opcional e pode ser omitida, mas sozinha não especifica qual lado preservar.
Alternativa E — ✅ Correta ⟵ GABARITO
O RIGHT JOIN preserva todas as linhas da tabela à direita (tb_cliente). Assim, todos os clientes aparecem no resultado, inclusive aqueles sem empréstimo. Para esses clientes, as colunas de tb_emprestimo (incluindo id_financeira) serão NULL, e a condição WHERE e.id_financeira IS NULL seleciona exatamente esses registros.
NÃO CAIA NESSA!
A banca inverte a ordem das tabelas no FROM para confundir. Como tb_cliente está à direita, muitos candidatos pensam em LEFT JOIN (que preservaria tb_emprestimo), mas o correto é RIGHT JOIN para preservar tb_cliente. Lembre-se: o LEFT/RIGHT se refere à posição da tabela na cláusula FROM, não à ordem lógica da consulta.