Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — CESPE / CEBRASPE 2025

Banco de DadosConsultas e Comandos em SQL
Código
ce417358
Banca
CESPE / CEBRASPE
Órgão
SEFAZ SE
Ano
2025
Cargo
AFT ( )

A tabela VENDAS tem a seguinte estrutura simplificada.

 

VENDAS(

     ID_VENDA    INT,

     ID_CLIENTE  INT,

     VALOR       DECIMAL(10,2),

DATA_VENDA       DATE

);

 

Dessa tabela, deseja-se obter, para cada cliente, o total de vendas realizadas e, em seguida, apresentar o ranking desses clientes, ordenado do maior para o menor valor total.

 

A partir das informações precedentes, assinale a opção na qual é apresentada a consulta SQL que atenderá ao desejado.

  1. ASELECT ID_CLIENTE, SUM(VALOR) AS TOTAL,      RANK() OVER (ORDER BY SUM(VALOR) DESC) AS POSICAO FROM VENDAS ORDER BY ID_CLIENTE;
  2. BSELECT ID_CLIENTE, SUM(VALOR) AS TOTAL FROM VENDAS ORDER BY SUM(VALOR) DESC;
  3. CSELECT ID_CLIENTE, SUM(VALOR) AS TOTAL,     RANK() OVER (ORDER BY SUM(VALOR) DESC) AS POSICAO FROM VENDAS GROUP BY ID_CLIENTE ORDER BY TOTAL DESC;
  4. DSELECT ID_CLIENTE, RANK() OVER (ORDER BY SUM(VALOR) DESC) AS POSICAO FROM VENDAS ORDER BY POSICAO;
  5. ESELECT ID_CLIENTE, SUM(VALOR) AS TOTAL,      RANK() OVER (ORDER BY TOTAL DESC) AS POSICAO FROM VENDAS ORDER BY TOTAL DESC;
Revelar gabarito e comentário

GabaritoC — SELECT ID_CLIENTE, SUM(VALOR) AS TOTAL,     RANK() OVER (ORDER BY SUM(VALOR) DESC) AS POSICAO FROM VENDAS GROUP BY ID_CLIENTE ORDER BY TOTAL DESC;

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

SQL – Funções de janela, agregação e ranking

Gabarito: letra C. A consulta correta precisa agrupar as vendas por cliente (GROUP BY ID_CLIENTE), calcular o total com SUM(VALOR), atribuir a posição no ranking com a função de janela RANK() OVER (ORDER BY SUM(VALOR) DESC) e, por fim, ordenar o resultado pelo total decrescente (ORDER BY TOTAL DESC). A alternativa C é a única que combina todos esses elementos na ordem sintática correta.

O problema pede duas coisas distintas: (1) o total de vendas por cliente e (2) um ranking desses clientes, do maior para o menor total. A primeira exigência é uma típica operação de agregação: precisamos agrupar as linhas da tabela VENDAS por ID_CLIENTE e somar o VALOR de cada grupo. Isso se faz com GROUP BY ID_CLIENTE e SUM(VALOR). Sem o GROUP BY, o SUM(VALOR) seria calculado sobre todas as linhas da tabela, devolvendo um único total geral — e não um total por cliente.

A segunda exigência — o ranking — é resolvida com uma função de janela (window function). Diferentemente das funções de agregação comuns, que colapsam várias linhas em uma só, as funções de janela calculam um valor para cada linha do resultado, com base em um conjunto de linhas definido pela cláusula OVER. A função RANK() atribui uma posição sequencial (1, 2, 3...) a cada linha, e o ORDER BY dentro do OVER define o critério de ordenação para a numeração. Quando há empate nos valores, RANK() atribui a mesma posição aos empatados e pula a(s) posição(ões) seguinte(s) — por exemplo, dois clientes com o mesmo total ficam ambos na posição 1, e o próximo fica na posição 3.

A ordem lógica de execução das cláusulas em SQL é um ponto crucial aqui. O banco executa a consulta na seguinte sequência conceitual: FROMWHEREGROUP BYHAVINGSELECT (incluindo as funções de janela) → ORDER BY. Isso significa que, dentro da cláusula SELECT, a função de janela RANK() OVER (ORDER BY SUM(VALOR) DESC) já enxerga os grupos formados pelo GROUP BY e pode usar a agregação SUM(VALOR) como critério de ordenação. Já a cláusula ORDER BY final, que vem depois do SELECT, pode referenciar o apelido TOTAL criado na projeção — por isso ORDER BY TOTAL DESC funciona.

Vamos analisar cada alternativa para ver onde cada uma falha:

  1. 1GROUP BY ID_CLIENTE
  2. 2SUM(VALOR) AS TOTAL
  3. 3RANK() OVER (ORDER BY SUM(VALOR) DESC)
  4. 4ORDER BY TOTAL DESC
LEVEL · soulevel.com.br

Alternativa A — ❌ Incorreta

Falta o GROUP BY ID_CLIENTE. Sem ele, o SUM(VALOR) é calculado sobre todas as linhas da tabela, produzindo um único total geral — não um total por cliente. Além disso, o ORDER BY ID_CLIENTE no final ordena pelo código do cliente, não pelo total, o que contraria o pedido de ordenar do maior para o menor valor. A função RANK() até está sintaticamente correta, mas opera sobre um resultado sem agrupamento, o que não atende ao objetivo.

Alternativa B — ❌ Incorreta

Falta a função de janela RANK(). A consulta apenas calcula o total por cliente (GROUP BY ID_CLIENTE + SUM(VALOR)) e ordena pelo total decrescente (ORDER BY SUM(VALOR) DESC). Isso entrega o total de vendas por cliente ordenado, mas não atribui a posição no ranking — que é justamente o que o enunciado pede. O ORDER BY SUM(VALOR) DESC é válido, mas a ausência do RANK() torna a consulta incompleta.

Alternativa C — ✅ Correta ⟵ GABARITO

Esta é a consulta completa e correta. O GROUP BY ID_CLIENTE agrupa as vendas por cliente; o SUM(VALOR) AS TOTAL calcula o total de cada grupo; o RANK() OVER (ORDER BY SUM(VALOR) DESC) atribui a posição no ranking, ordenando os grupos pelo total decrescente; e o ORDER BY TOTAL DESC final ordena o resultado final pelo total, do maior para o menor. A ordem das cláusulas está correta: GROUP BY antes do SELECT (que contém a função de janela) e ORDER BY por último.

Alternativa D — ❌ Incorreta

Falta o SUM(VALOR) na projeção. A consulta seleciona apenas ID_CLIENTE e a posição do ranking, sem exibir o total de vendas de cada cliente — que é um dado essencial pedido no enunciado. Além disso, o RANK() OVER (ORDER BY SUM(VALOR) DESC) está sintaticamente correto, mas sem o GROUP BY ID_CLIENTE o SUM(VALOR) seria calculado sobre todas as linhas, e o ranking seria atribuído a cada linha individual, não a cada cliente. O ORDER BY POSICAO também não é o critério pedido (ordenar pelo total).

Alternativa E — ❌ Incorreta

O erro está no RANK() OVER (ORDER BY TOTAL DESC): a função de janela referencia o apelido TOTAL, mas, na ordem de execução lógica do SQL, a cláusula OVER é avaliada dentro do SELECT, antes que o apelido TOTAL seja definido. Nesse contexto, o banco não reconhece TOTAL como uma coluna válida — ele só existe após a projeção ser concluída. O correto seria usar SUM(VALOR) diretamente dentro do OVER, como na alternativa C. O ORDER BY TOTAL DESC final, por outro lado, é válido, pois a cláusula ORDER BY é avaliada depois do SELECT.

NÃO CAIA NESSA!

A banca explora a diferença entre a ordem de escrita e a ordem de execução das cláusulas SQL. Na alternativa E, o apelido TOTAL é usado dentro do OVER, mas ele só existe depois que o SELECT termina — por isso o erro. Já na alternativa A, a ausência do GROUP BY faz o SUM virar um total geral. Fique atento: dentro do OVER, use a expressão de agregação (SUM(VALOR)), não o apelido; no ORDER BY final, o apelido é permitido.

PEGA ESSA DICA!

Para questões de ranking com agregação, monte o esqueleto mental: SELECT colunas + agregação + RANK() OVER (ORDER BY agregação DESC) + FROM + GROUP BY coluna de agrupamento + ORDER BY apelido da agregação. Confira sempre se o GROUP BY está presente e se o OVER usa a expressão de agregação, não o apelido.

Gabarito: letra C

Link permanente: /questoes/ce417358