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

AzulVerde
AB
CA
BA
CE
FA
FD
 

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:

  1. Anenhum dos scripts funciona;
  2. Bsomente o primeiro script funciona;
  3. Csomente o segundo script funciona;
  4. Dsomente o terceiro script funciona;
  5. 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).

Vamos calcular manualmente:

  • A: Azul = 1 (linha 1), Verde = 2 (linhas 2 e 3) → 1 ≠ 2

  • B: Azul = 1 (linha 3), Verde = 1 (linha 1) → 1 = 1 ✅

  • C: Azul = 2 (linhas 2 e 4), Verde = 0 → 2 ≠ 0

  • D: Azul = 0, Verde = 1 (linha 6) → 0 ≠ 1

  • E: Azul = 0, Verde = 1 (linha 4) → 0 ≠ 1

  • F: Azul = 2 (linhas 5 e 6), Verde = 0 → 2 ≠ 0

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.

Gabarito: letra C

Link permanente: /questoes/fg165218