Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2024
Banco de Dados›Consultas e Comandos em SQL
Código
fg165260
Banca
FGV
Órgão
CVM
Ano
2024
Cargo
Ana ( )
Observe o script SQL a seguir.
CREATE TABLE AUDITOR (ID_A INT NOT NULL, Nome varchar(20),PRIMARY KEY (ID_A)); CREATE TABLE AUDITADO (ID_O INT NOT NULL, Nome varchar(20), ID_A INT, PRIMARY KEY (ID_O),FOREIGN KEY (ID_A) REFERENCES AUDITOR(ID_A)); INSERT INTO AUDITOR (ID_A, Nome) VALUES (1, 'Maite'); INSERT INTO AUDITOR (ID_A, Nome) VALUES (2, 'Lucca'); INSERT INTO AUDITOR (ID_A, Nome) VALUES (3, 'Maria Clara'); INSERT INTO AUDITADO (ID_O, Nome, ID_A) VALUES (1, 'Felipe', 1); INSERT INTO AUDITADO (ID_O, Nome, ID_A) VALUES (2, 'Stella', 2); INSERT INTO AUDITADO (ID_O, Nome, ID_A) VALUES (3, 'Patricia', NULL);
Para analisar quais auditores estão realizando auditoria em quais auditados, é necessária a execução de uma consulta SQL que apresente o seguinte resultado:
Auditor
Auditado
Maite
Felipe
Lucca
Stella
Para obter o resultado apresentado, deve-se executar a consulta SQL:
ASELECT AUDITOR.Nome as 'Auditor' FROM AUDITOR WHERE AUDITOR.ID_A = ALL (SELECT AUDITADO.Nome as 'Auditado' FROM AUDITADO WHERE AUDITADO.ID_A=AUDITOR.ID_A);
BSELECT AUDITOR.Nome as 'Auditor', AUDITADO.Nome as 'Auditado' FROM AUDITOR, AUDITADO HAVING AUDITADO.ID_A=AUDITOR.ID_A;
CSELECT AUDITOR.Nome as 'Auditor', AUDITADO.Nome as 'Auditado' FROM AUDITOR INNER JOIN AUDITADO ON AUDITADO.ID_A=AUDITOR.ID_A;
DSELECT AUDITOR.Nome as 'Auditor' FROM AUDITOR WHERE EXISTS (SELECT AUDITADO.Nome as 'Auditado' FROM AUDITADO WHERE AUDITADO.ID_A=AUDITOR.ID_A);
ESELECT AUDITOR.Nome as 'Auditor' FROM AUDITOR UNION SELECT AUDITADO.Nome as 'Auditado' FROM AUDITADO;
Revelar gabarito e comentário▾
GabaritoC — SELECT AUDITOR.Nome as 'Auditor', AUDITADO.Nome as 'Auditado'
FROM AUDITOR INNER JOIN AUDITADO ON
AUDITADO.ID_A=AUDITOR.ID_A;
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”.
Consultas SQL: INNER JOIN e a junção de tabelas
Gabarito: letra C. A consulta que produz exatamente o resultado pedido (Maite–Felipe e Lucca–Stella) é a que usa INNER JOIN com a condição AUDITADO.ID_A = AUDITOR.ID_A, pois essa junção combina apenas as linhas das duas tabelas que possuem valores correspondentes na chave estrangeira. As demais alternativas ou estão sintaticamente incorretas, ou retornam um conjunto de dados diferente do esperado.
O problema pede para cruzar as tabelas AUDITOR e AUDITADO e listar, lado a lado, o nome do auditor e o nome do auditado, mas somente para os pares que realmente possuem um vínculo — ou seja, onde o ID_A do auditado referencia um auditor existente. No script fornecido, temos três auditores (Maite, Lucca e Maria Clara) e três auditados (Felipe, Stella e Patrícia). O auditado Patrícia possui ID_A = NULL, o que significa que ela não está associada a nenhum auditor. Portanto, ela não deve aparecer no resultado. O resultado esperado mostra apenas os dois pares válidos: Maite–Felipe e Lucca–Stella.
A ferramenta correta para esse tipo de consulta é a junção interna (INNER JOIN), que combina registros de duas tabelas com base em uma condição de igualdade entre colunas relacionadas. A sintaxe básica é SELECT ... FROM tabela1 INNER JOIN tabela2 ON condição. Essa junção retorna apenas as linhas onde a condição é verdadeira, descartando automaticamente os registros sem correspondência — exatamente o que precisamos para excluir Patrícia do resultado.
É importante distinguir a junção interna das junções externas (LEFT JOIN, RIGHT JOIN, FULL JOIN). Enquanto a INNER JOIN exige correspondência em ambas as tabelas, a LEFT JOIN retorna todas as linhas da tabela à esquerda, mesmo que não haja correspondência na direita (preenchendo com NULL). Se usássemos LEFT JOIN com AUDITOR à esquerda, Maria Clara apareceria no resultado com um auditado NULL, o que não é o desejado. A INNER JOIN é, portanto, a escolha precisa para o cenário apresentado.
A pegadinha da questão está em duas frentes: primeiro, na alternativa B, que usa HAVING sem GROUP BY — uma cláusula que serve para filtrar grupos agregados, não para fazer junções; segundo, nas alternativas A e D, que usam subconsultas para retornar apenas o nome do auditor, sem conseguir listar o auditado correspondente na mesma linha. A alternativa E, por sua vez, usa UNION, que simplesmente concatena os nomes de ambas as tabelas em uma única coluna, sem qualquer relação entre eles. A única alternativa que implementa corretamente a junção é a letra C.
Guarde o critério decisivo: para cruzar duas tabelas e exibir colunas de ambas, a ferramenta é a junção (JOIN), e a INNER JOIN é a que filtra apenas os pares com correspondência. É exatamente nesse ponto que as alternativas se dividem.
Tipos de JOIN: INNER JOIN (Só pares com correspondência, Exclui NULL e sem par); LEFT JOIN (Mantém todos da esquerda, Preenche com NULL); RIGHT JOIN (Mantém todos da direita); FULL JOIN (Mantém todos de ambos)
Alternativa A — ❌ Incorreta
Esta consulta tenta usar WHERE AUDITOR.ID_A = ALL (SELECT ...). A sintaxe = ALL é usada para comparar um valor com todos os valores de uma subconsulta, mas aqui a subconsulta retorna AUDITADO.Nome (uma string), enquanto a comparação é feita com AUDITOR.ID_A (um inteiro). Além disso, a consulta principal seleciona apenas AUDITOR.Nome, sem incluir o nome do auditado, então o resultado não teria a segunda coluna 'Auditado'. Mesmo que a sintaxe fosse corrigida, a lógica não produziria o par auditor–auditado na mesma linha.
Alternativa B — ❌ Incorreta
A cláusula HAVING é usada para filtrar grupos de linhas após a agregação com GROUP BY. Nesta consulta, não há GROUP BY, e a cláusula HAVING está sendo usada indevidamente como se fosse um WHERE. Além disso, a consulta faz um produto cartesiano entre AUDITOR e AUDITADO (sem JOIN ou WHERE), o que geraria todas as combinações possíveis (3 × 3 = 9 linhas), e o HAVING tentaria filtrar, mas sem agrupamento isso é inválido na maioria dos bancos de dados. O resultado não seria o esperado.
Alternativa C — ✅ Correta ⟵ GABARITO
Esta é a consulta correta. Ela usa INNER JOIN com a condição AUDITADO.ID_A = AUDITOR.ID_A, que combina as linhas das duas tabelas onde o ID_A do auditado corresponde ao ID_A do auditor. O resultado será:
Auditor
Auditado
Maite
Felipe
Lucca
Stella
A linha de Patrícia (com ID_A = NULL) é descartada porque NULL não é igual a nenhum valor, e a linha de Maria Clara (sem auditados associados) também é excluída, pois não há correspondência. O INNER JOIN é a ferramenta exata para esse tipo de cruzamento.
Alternativa D — ❌ Incorreta
Esta consulta usa WHERE EXISTS (SELECT ...), que retorna TRUE se a subconsulta retornar pelo menos uma linha. A subconsulta verifica se existe um auditado com ID_A igual ao ID_A do auditor. Isso retornaria os auditores Maite e Lucca (que têm auditados associados), mas a consulta principal seleciona apenas AUDITOR.Nome, sem incluir o nome do auditado. Portanto, o resultado teria apenas uma coluna 'Auditor', não as duas colunas 'Auditor' e 'Auditado' como exigido.
Alternativa E — ❌ Incorreta
O comando UNION combina os resultados de duas consultas em uma única lista, eliminando duplicatas. Aqui, ele une os nomes dos auditores com os nomes dos auditados em uma única coluna. O resultado seria uma lista vertical com os nomes: Maite, Lucca, Maria Clara, Felipe, Stella, Patrícia. Isso não produz o par auditor–auditado lado a lado, e ainda incluiria Maria Clara e Patrícia, que não deveriam aparecer.
A regra de ouro para levar à prova: quando o objetivo é exibir colunas de duas tabelas relacionadas, use JOIN — e INNER JOIN quando quiser apenas os registros com correspondência em ambas. As junções externas (LEFT, RIGHT, FULL) preservam linhas sem par, o que não é o caso aqui.