Questão de Banco de Dados — Consultas e Comandos em SQL — FGV 2024
Banco de Dados›Consultas e Comandos em SQL
Código
fg165218
Banca
FGV
Órgão
TJ AP
Ano
2024
Cargo
AJ ( )
Quando referenciadas, considere as tabelas relacionais Competidor e Disputa, cujas estruturas e instâncias são descritas abaixo. Todas as colunas são definidas como strings.
A tabela Disputa contém as disputas realizadas entre competidores que aparecem na tabela Competidor. Em cada disputa há dois competidores, um com camisa azul e outro com camisa verde.
Competidor
Nome
A
B
C
D
E
F
Disputa
Azul
Verde
A
B
C
A
B
A
C
E
F
A
F
D
João tem pouca experiência com SQL, mas precisa de uma consulta que exiba os competidores que têm o mesmo número de disputas com as camisas azul e verde. João escreveu três scripts, utilizando as tabelas Competidor e Disputa, como definidas anteriormente, e tentou a sorte.
select distinct c.nome
from Competidor c, Disputa d
group by c.nome
having count(distinct d.azul)
= count(distinct d.verde)
select c.nome
from Competidor c
where (select sum(1)
from Disputa d where d.azul = c.nome)
= (select sum(1)
from Disputa d where d.verde = c.nome)
select distinct c.nome
from Competidor c, Disputa d
where (select sum(1) where d.azul = c.nome)
= (select sum(1) where d.verde = c.nome)
Dado que a resposta correta deve exibir somente o competidor B, conclui-se que:
Anenhum dos scripts funciona;
Bsomente o primeiro script funciona;
Csomente o segundo script funciona;
Dsomente o terceiro script funciona;
Eos três scripts funcionam.
Revelar gabarito e comentário▾
GabaritoC — somente o segundo script funciona;
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: contagem de disputas por competidor
Gabarito: letra C — somente o segundo script funciona. O segundo script usa subconsultas correlacionadas com sum(1) para contar, para cada competidor, quantas vezes ele aparece na coluna azul e quantas vezes na coluna verde, comparando os dois totais. O primeiro script falha porque count(distinct d.azul) conta valores distintos, não ocorrências, e o terceiro script é sintaticamente inválido, pois a subconsulta (select sum(1) where d.azul = c.nome) não referencia a tabela Disputa no FROM.
O problema pede para identificar competidores que participaram do mesmo número de disputas com camisa azul e com camisa verde. Vamos analisar os dados fornecidos:
Tabela Disputa:
Azul
Verde
A
B
C
A
B
A
C
E
F
A
F
D
Para cada competidor, precisamos contar:
Quantas vezes ele aparece na coluna Azul (disputas em que usou camisa azul).
Quantas vezes ele aparece na coluna Verde (disputas em que usou camisa verde).
Portanto, apenas o competidor B tem o mesmo número de disputas com as duas cores (1 azul e 1 verde).
Agora, vamos analisar cada script:
Script 1 — ❌ Incorreto
select distinct c.nome
from Competidor c, Disputa d
group by c.nome
having count(distinct d.azul) = count(distinct d.verde)
Este script usa count(distinct d.azul) e count(distinct d.verde). O DISTINCT faz com que a contagem considere apenas valores únicos, não ocorrências. Como a coluna azul tem valores repetidos (A, C, B, C, F, F), count(distinct d.azul) retorna 4 (A, B, C, F), e count(distinct d.verde) retorna 4 (B, A, E, D). Como 4 = 4, o HAVING seria verdadeiro para todos os grupos, e o resultado incluiria todos os competidores, não apenas B. Além disso, o GROUP BY c.nome com c e d em produto cartesiano gera um resultado incorreto, pois cada linha de Competidor é combinada com todas as linhas de Disputa, inflando a contagem. O DISTINCT no SELECT não corrige o problema da contagem errada.
Script 2 — ✅ Correto
select c.nome
from Competidor c
where (select sum(1) from Disputa d where d.azul = c.nome)
= (select sum(1) from Disputa d where d.verde = c.nome)
Este script usa subconsultas correlacionadas. Para cada competidor c, a primeira subconsulta conta quantas vezes c.nome aparece na coluna azul (usando sum(1), que soma 1 para cada linha que satisfaz a condição). A segunda subconsulta conta quantas vezes c.nome aparece na coluna verde. A condição = compara os dois totais. Para B, ambas as contagens são 1, então B é retornado. Para os demais, as contagens diferem, então não são retornados. O resultado é exatamente o esperado: somente B.
Script 3 — ❌ Incorreto
select distinct c.nome
from Competidor c, Disputa d
where (select sum(1) where d.azul = c.nome)
= (select sum(1) where d.verde = c.nome)
Este script é sintaticamente inválido. As subconsultas (select sum(1) where d.azul = c.nome) não possuem cláusula FROM, então não referenciam a tabela Disputa. Em SQL padrão, uma subconsulta sem FROM não pode referenciar colunas de tabelas externas (a menos que seja uma subconsulta correlacionada com FROM explícito). Além disso, a referência d.azul e d.verde dentro da subconsulta não é válida porque d não está definida no escopo da subconsulta. Portanto, o script não executa.
Conclusão: apenas o segundo script funciona corretamente, retornando somente o competidor B. Portanto, a alternativa correta é a letra C.
PEGA ESSA DICA!
Para contar ocorrências em SQL, use COUNT(*) ou SUM(1) — ambos contam linhas. COUNT(DISTINCT coluna) conta valores únicos, o que é diferente. Quando precisar comparar contagens de ocorrências, prefira subconsultas correlacionadas com COUNT(*) ou SUM(1), como no script 2.