Considere a tabela VENDA(id_venda, id_cliente, nome_cliente, id_produto, nome_produto, quantidade, valor_unitario) em um banco de dados MySQL. Um analista percebe que o banco apresenta redundâncias e decide normalizar a estrutura antes de otimizar as consultas. Após decompor a tabela até a 3FN, ele obtém as relações CLIENTE(id_cliente, nome_cliente), PRODUTO(id_produto, nome_produto, valor_unitario) e VENDA(id_venda, id_cliente, id_produto, quantidade). Assinale a alternativa que apresenta a consulta SQL correta para retornar o nome do cliente, o nome do produto e o valor total de cada venda após a normalização.
ASELECT c.nome_cliente, p.nome_produto, v.quantidade * p.valor_unitario AS valor_total FROM venda v INNER JOIN cliente c ON v.id_cliente = c.id_cliente INNER JOIN produto p ON v.id_produto = p.id_produto ORDER BY valor_total DESC;
BSELECT nome_cliente, nome_produto, quantidade * valor_unitario AS valor_total FROM venda ORDER BY valor_total DESC;
CSELECT c.nome_cliente, p.nome_produto, SUM(v.quantidade * p.valor_unitario) AS valor_total FROM venda v, cliente c, produto p WHERE v.id_cliente = c.id_cliente GROUP BY v.id_venda ORDER BY valor_total DESC;
DSELECT c.nome_cliente, p.nome_produto, v.quantidade * p.valor_unitario AS valor_total FROM venda v LEFT JOIN cliente c ON v.id_cliente = c.id_cliente LEFT JOIN produto p ON v.id_produto = p.id_produto WHERE valor_total > 0 ORDER BY valor_total DESC;
ESELECT c.nome_cliente, p.nome_produto, MAX(v.quantidade * p.valor_unitario) AS valor_total FROM venda v INNER JOIN cliente c ON v.id_cliente = c.id_cliente INNER JOIN produto p ON v.id_produto = p.id_produto GROUP BY v.id_venda;
Revelar gabarito e comentário▾
GabaritoA — SELECT c.nome_cliente, p.nome_produto,
v.quantidade * p.valor_unitario AS valor_total
FROM venda v
INNER JOIN cliente c ON v.id_cliente = c.id_cliente
INNER JOIN produto p ON v.id_produto = p.id_produto
ORDER BY valor_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”.
Consulta SQL após normalização: JOINs e cálculo de valor total
Gabarito: letra A. Após a normalização, o valor unitário do produto passou a residir exclusivamente na tabela PRODUTO, e a quantidade na tabela VENDA. Para retornar o nome do cliente, o nome do produto e o valor total de cada venda, é obrigatório unir as três tabelas (VENDA, CLIENTE e PRODUTO) por meio de INNER JOIN e calcular quantidade * valor_unitario — exatamente o que a alternativa A faz. As demais alternativas ou ignoram a necessidade de junção, ou usam agregação indevida, ou empregam junção externa desnecessária.
A normalização é o processo de reorganizar as tabelas de um banco de dados relacional para minimizar redundâncias e anomalias de inserção, exclusão e atualização, com base nas dependências funcionais e nas chaves primárias. No caso, a tabela original VENDA concentrava dados de clientes, produtos e vendas em uma única estrutura, gerando repetição desnecessária de nomes e valores. Ao decompor até a 3FN, separamos:
CLIENTE(id_cliente, nome_cliente) — dados do cliente;
PRODUTO(id_produto, nome_produto, valor_unitario) — dados do produto, incluindo o preço unitário;
VENDA(id_venda, id_cliente, id_produto, quantidade) — dados específicos da venda, com as chaves estrangeiras para as outras tabelas.
A consequência prática é que nenhuma tabela isolada contém todos os dados necessários para a consulta pedida. O nome do cliente está em CLIENTE, o nome do produto e o valor unitário estão em PRODUTO, e a quantidade está em VENDA. Portanto, a consulta precisa combinar as três tabelas por meio de junções (JOINs), usando as chaves estrangeiras como condição de igualdade.
O INNER JOIN é a junção que retorna apenas as linhas que possuem correspondência nas duas tabelas envolvidas. Como toda venda deve ter um cliente e um produto válidos (integridade referencial), o INNER JOIN é a escolha correta — não há motivo para usar LEFT JOIN, que preservaria vendas sem cliente ou sem produto (o que não deveria existir).
O cálculo do valor total de cada venda é simples: quantidade * valor_unitario. Como o valor unitário está na tabela PRODUTO, a expressão deve referenciar a coluna qualificada p.valor_unitario. Não há necessidade de SUM, MAX ou GROUP BY, pois cada linha da tabela VENDA representa uma venda individual — a consulta deve retornar uma linha por venda, não um agregado.
A pegadinha central desta questão é que, após a normalização, a consulta não pode mais ser feita em uma única tabela. O candidato que tenta usar apenas a tabela VENDA (alternativa B) ou que esquece de juntar PRODUTO para obter o valor unitário comete erro. Além disso, o uso de SUM ou MAX com GROUP BY (alternativas C e E) agruparia vendas, o que não é o que se pede — queremos o valor total de cada venda, não um total agregado.
Guarde o critério decisivo: após a normalização, toda consulta que envolve dados de mais de uma tabela exige JOIN explícito, e o cálculo de valor total por venda é uma multiplicação simples, sem agregação. É exatamente nesse ponto que as alternativas se dividem.
Critério
Alternativa A (✅ correta)
Alternativa B
Alternativa C
Alternativa D
Alternativa E
Junção entre tabelas
INNER JOIN nas 3 tabelas (VENDA, CLIENTE, PRODUTO)
Usa WHERE valor_total > 0 (inválido — alias não pode ser referenciado no WHERE)
Não usa
Resultado esperado
Nome do cliente, nome do produto e valor total de cada venda
Falha (colunas não existem em VENDA)
Retorna valores, mas com agregação redundante
Erro de sintaxe (alias no WHERE)
Retorna valores, mas com agregação semântica incorreta
Alternativa A — ✅ Correta ⟵ GABARITO
A alternativa A está correta porque:
Usa INNER JOIN para combinar as três tabelas, com as condições corretas: v.id_cliente = c.id_cliente e v.id_produto = p.id_produto.
Seleciona os campos desejados com qualificação de tabela (c.nome_cliente, p.nome_produto), evitando ambiguidade.
Calcula o valor total como v.quantidade * p.valor_unitario, usando o valor unitário da tabela PRODUTO (que é onde ele reside após a normalização).
Ordena por valor_total DESC, atendendo ao pedido de ordenação.
A sintaxe está correta e a lógica é exatamente a necessária para a consulta pós-normalização.
Alternativa B — ❌ Incorreta
A alternativa B está incorreta porque consulta apenas a tabela VENDA, sem realizar nenhum JOIN. Após a normalização, a tabela VENDA não contém as colunas nome_cliente, nome_produto nem valor_unitario — esses dados foram movidos para as tabelas CLIENTE e PRODUTO. A consulta falharia com erro de coluna inexistente. Além disso, mesmo que existissem, a lógica estaria errada por não refletir a estrutura normalizada.
Alternativa C — ❌ Incorreta
A alternativa C está incorreta por dois motivos:
Usa junção implícita (vírgula na cláusula FROM) com condição no WHERE — embora funcione, é uma sintaxe antiga e menos clara, mas não é o erro principal.
Usa SUM(v.quantidade * p.valor_unitario) com GROUP BY v.id_venda. Como cada id_venda é único na tabela VENDA, o SUM não agrega nada — mas a presença de GROUP BY e função agregada é desnecessária e semanticamente incorreta para o que se pede (retornar o valor total de cada venda, não um total agrupado). A consulta até poderia retornar os valores corretos, mas a agregação é redundante e pode induzir a erro em outros contextos.
Alternativa D — ❌ Incorreta
A alternativa D está incorreta porque usa LEFT JOIN em vez de INNER JOIN. O LEFT JOIN preservaria todas as linhas da tabela VENDA, mesmo aquelas sem correspondência em CLIENTE ou PRODUTO, retornando valores NULL para os campos dessas tabelas. Como a integridade referencial garante que toda venda tem cliente e produto, o LEFT JOIN é desnecessário e poderia mascarar problemas de dados. Além disso, a cláusula WHERE valor_total > 0 é inválida, pois não é possível referenciar um alias na cláusula WHERE — o alias valor_total só pode ser usado no ORDER BY ou no HAVING (em alguns bancos). Isso geraria erro de sintaxe.
Alternativa E — ❌ Incorreta
A alternativa E está incorreta porque usa MAX(v.quantidade * p.valor_unitario) com GROUP BY v.id_venda. A função MAX retornaria o maior valor do grupo — mas como cada id_venda é único, o MAX retornaria o próprio valor, o que até funcionaria na prática. Porém, o uso de função agregada e GROUP BY é semanticamente incorreto para a consulta pedida: queremos o valor total de cada venda, não o máximo de um grupo. A agregação é desnecessária e confusa, e a consulta não atende ao espírito da questão.