Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2024

Banco de DadosConsultas e Comandos em SQL
Código
fg165238
Banca
FGV
Órgão
TJ MS
Ano
2024
Cargo
Tec NS ( )

Considere as seguintes tabelas, com suas respectivas colunas, que se relacionam pela coluna FornecedorID:

 

Produto (ProdutoID, ProdutoNome, FornecedorID)

Fornecedor (FornecedorID, FornecedorNome)

 

Para retornar a lista, sem repetições, de Fornecedores que possuem Produtos com preços menores que 20, deve-se executar o comando SQL:

  1. ASELECT FornecedorNome   FROM Fornecedor   WHERE EXISTS (SELECT ProdutoNome FROM Produto   WHERE Produto.FornecedorID =   Fornecedor.FornecedorID AND Preco < 20)
  2. BSELECT COUNT(FornecedorID), FornecedorNome    FROM Fornecedor, Produto    GROUP BY FornecedorID    HAVING COUNT(Preco) < 20
  3. CSELECT FornecedorNome    FROM Fornecedor    INNER JOIN Produto ON Produto.FornecedorID =    Fornecedor.FornecedorID AND Preco < 20
  4. DSELECT FornecedorNome FROM Fornecedor    UNION    SELECT ProdutoNome FROM Produto    WHERE Preco < 20)
  5. ESELECT FornecedorNome    FROM Fornecedor    WHERE FornecedorID = ANY (    SELECT ProdutoID    FROM Produto WHERE Preco < 20)
Revelar gabarito e comentário

GabaritoA — SELECT FornecedorNome   FROM Fornecedor   WHERE EXISTS (SELECT ProdutoNome FROM Produto   WHERE Produto.FornecedorID =   Fornecedor.FornecedorID AND Preco < 20)

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”.

Consulta SQL com EXISTS: Fornecedores com Produtos Baratos

Gabarito: letra A. A consulta correta usa a subconsulta correlacionada com o operador EXISTS, que retorna verdadeiro se existir pelo menos um produto do fornecedor com preço menor que 20, garantindo que cada fornecedor apareça apenas uma vez na lista. As demais alternativas falham por usar operadores ou lógicas inadequadas, como COUNT com HAVING, JOIN sem DISTINCT, UNION com colunas incompatíveis ou ANY comparando colunas erradas.

O comando SELECT é a base da consulta em SQL, e a questão exige entender como combinar duas tabelas relacionadas por FornecedorID para filtrar fornecedores que possuem produtos com preço abaixo de 20. A tabela Produto tem as colunas ProdutoID, ProdutoNome, FornecedorID e, implicitamente, Preco (mencionado nas alternativas). A tabela Fornecedor tem FornecedorID e FornecedorNome. O objetivo é retornar os nomes dos fornecedores que têm pelo menos um produto com Preco < 20, sem repetições.

A solução ideal usa uma subconsulta correlacionada com EXISTS. Nesse padrão, para cada fornecedor da consulta externa, a subconsulta interna verifica se existe algum produto cujo FornecedorID seja igual ao do fornecedor atual e cujo Preco seja menor que 20. Se a subconsulta retornar pelo menos uma linha, o EXISTS é verdadeiro e o fornecedor é incluído no resultado. Como a consulta externa seleciona apenas FornecedorNome da tabela Fornecedor, cada fornecedor aparece uma única vez, atendendo ao requisito de "sem repetições".

O operador EXISTS é eficiente porque para cada linha da tabela externa, ele executa a subconsulta e para na primeira correspondência, sem precisar processar todas as linhas da tabela interna. Isso é diferente de um JOIN, que combinaria todas as linhas correspondentes e poderia gerar duplicatas, exigindo DISTINCT para eliminar repetições.

A alternativa A está correta porque usa exatamente essa lógica. A subconsulta correlacionada referencia a tabela externa Fornecedor através de Fornecedor.FornecedorID, e a condição Preco < 20 filtra os produtos baratos. O EXISTS garante que apenas fornecedores com pelo menos um produto barato sejam retornados, e como a seleção é feita na tabela Fornecedor, não há repetição de nomes.

As demais alternativas apresentam erros conceituais:

  • A alternativa B usa COUNT(FornecedorID) e HAVING COUNT(Preco) < 20, o que não faz sentido: COUNT conta linhas, não soma preços, e a condição HAVING compara uma contagem com 20, não filtra produtos com preço menor que 20.

  • A alternativa C usa INNER JOIN sem DISTINCT, o que pode retornar o mesmo fornecedor várias vezes se ele tiver múltiplos produtos baratos, violando o requisito de "sem repetições".

  • A alternativa D usa UNION entre FornecedorNome e ProdutoNome, que são colunas de tabelas diferentes e semanticamente incompatíveis, além de não filtrar corretamente os fornecedores.

  • A alternativa E usa ANY com uma subconsulta que retorna ProdutoID, mas compara com FornecedorID, o que é uma comparação incorreta entre colunas de naturezas diferentes.

A pegadinha da questão está em reconhecer que o JOIN sem DISTINCT gera duplicatas, e que EXISTS é a forma mais direta de verificar a existência de um relacionamento sem repetir linhas. O candidato que não domina subconsultas correlacionadas pode cair na alternativa C, que parece correta à primeira vista, mas falha no requisito de unicidade.

Alternativa A — ✅ Correta ⟵ GABARITO

A alternativa A está correta porque utiliza uma subconsulta correlacionada com EXISTS. Para cada fornecedor, a subconsulta verifica se existe um produto com FornecedorID igual e Preco < 20. Se existir, o EXISTS retorna verdadeiro e o fornecedor é incluído. Como a consulta externa seleciona apenas FornecedorNome da tabela Fornecedor, cada fornecedor aparece uma única vez, atendendo ao requisito de "sem repetições".

Alternativa B — ❌ Incorreta

A alternativa B está incorreta porque usa COUNT(FornecedorID) e HAVING COUNT(Preco) < 20. A função COUNT conta o número de linhas, não soma preços. A condição HAVING COUNT(Preco) < 20 compara a contagem de produtos com o valor 20, o que não tem relação com filtrar produtos com preço menor que 20. Além disso, a consulta não faz a junção correta entre as tabelas, pois usa um produto cartesiano implícito (FROM Fornecedor, Produto) sem condição de junção, o que pode gerar resultados incorretos.

Alternativa C — ❌ Incorreta

A alternativa C está incorreta porque usa INNER JOIN sem DISTINCT. Se um fornecedor tiver múltiplos produtos com preço menor que 20, o JOIN retornará uma linha para cada produto, fazendo o fornecedor aparecer várias vezes no resultado. O requisito do enunciado é "sem repetições", então seria necessário adicionar DISTINCT à consulta para eliminar duplicatas. Sem isso, a consulta viola o requisito.

Alternativa D — ❌ Incorreta

A alternativa D está incorreta porque usa UNION entre FornecedorNome e ProdutoNome. O UNION combina resultados de duas consultas, mas as colunas selecionadas devem ser compatíveis em tipo e significado. FornecedorNome e ProdutoNome são nomes de entidades diferentes, e a consulta não filtra corretamente os fornecedores que possuem produtos baratos. Além disso, a sintaxe tem um parêntese extra no final, o que a torna inválida.

Alternativa E — ❌ Incorreta

A alternativa E está incorreta porque usa ANY com uma subconsulta que retorna ProdutoID, mas compara com FornecedorID. A comparação FornecedorID = ANY (SELECT ProdutoID ...) compara uma coluna de fornecedor com uma coluna de produto, que são de naturezas diferentes e não têm relação direta. O correto seria comparar FornecedorID com FornecedorID na subconsulta, mas a subconsulta seleciona ProdutoID, tornando a comparação semanticamente incorreta.

Gabarito: letra A

Link permanente: /questoes/fg165238