Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Condição Case

Boa noite pessoal,

Fiquei com uma duvida, na aula de condições para classificar resultados. O professor colocou o case todo no group by. Como no exemplo abaixo:

SELECT [NOME DO PRODUTO],
CASE WHEN [PREÇO DE LISTA] >= 12 THEN 'PRODUTO CARO'
WHEN [PREÇO DE LISTA] >= 7 AND [PREÇO DE LISTA] < 12 THEN 'PRODUTO EM CONTA'
ELSE 'PRODUTO BARATO' END,
AVG([PREÇO DE LISTA])
FROM
[TABELA DE PRODUTOS]
GROUP BY [NOME DO PRODUTO],
CASE WHEN [PREÇO DE LISTA] >= 12 THEN 'PRODUTO CARO'
WHEN [PREÇO DE LISTA] >= 7 AND [PREÇO DE LISTA] < 12 THEN 'PRODUTO EM CONTA'
ELSE 'PRODUTO BARATO' END

Mais se eu colocar somente a tabela que eu estou usando no case, para fazer a condição eu acho o mesmo resultado.

SELECT [NOME DO PRODUTO],
CASE WHEN [PREÇO DE LISTA] >= 12 THEN 'PRODUTO CARO'
WHEN [PREÇO DE LISTA] >= 7 AND [PREÇO DE LISTA] < 12 THEN 'PRODUTO EM CONTA'
ELSE 'PRODUTO BARATO' END,
AVG([PREÇO DE LISTA])
FROM
[TABELA DE PRODUTOS]
GROUP BY [NOME DO PRODUTO],  [PREÇO DE LISTA]

Qual seria a diferença entre colocar o case todo no group by ou somente a tabela que estou usando ?

3 respostas

Olá, Vinicius, tudo bem?

A função de agregação AVG, retorna a média aritmética de um conjunto de valores. A média é obtida somando todos os valores e dividindo o valor encontrado pelo número de dados desse conjunto.

No exemplo utilizado pelo instrutor durante a aula, a utilização do AVG não faz muito sentido, já que o resultado final não é alterado. Porém, o foco principal da explicação é utilização da instrução CASE quando temos em uma consulta a cláusula group by.

Ao utilizarmos uma função de agregação, normalmente também precisamos informar a cláusula group by, que é utilizada para agrupar registros semelhantes de uma tabela em um ou mais campos. No SQL Server não é permitido realizar consultas onde os campos listados na seleção que não estão em uma função de agregação, não estão informadas na cláusula group by.

Como no exemplo utilizado pelo instrutor, na seleção temos o campo [NOME DO PRODUTO], a instrução CASE e o campoAVG([PREÇO DE LISTA]) que está dentro da função de agregação AVG, neste caso, precisamos informar na cláusula group by, todos os campos que não fazem parte da função de agregação, ou seja, o campo [NOME DO PRODUTO] a instrução CASE ou o campo [PREÇO DE LISTA] que faz parte da instrução CASE, precisam ser informados na cláusula group by, caso contrário, um erro será retornado:

SELECT [NOME DO PRODUTO],
CASE WHEN [PREÇO DE LISTA] >= 12 THEN 'PRODUTO CARO'
WHEN [PREÇO DE LISTA] >= 7 AND [PREÇO DE LISTA] < 12 THEN 'PRODUTO EM CONTA'
ELSE 'PRODUTO BARATO' END,
AVG([PREÇO DE LISTA])
FROM
[TABELA DE PRODUTOS]
GROUP BY [NOME DO PRODUTO]

Print da tela do SSMS onde o comando SQL anterior está sendo executado e o erro:  `Mensagem 8120, Nível 16, Estado 1, Linha 2
A coluna 'TABELA DE PRODUTOS.PREÇO DE LISTA' é inválida na lista de seleção porque não está contida em uma função de agregação nem na cláusula GROUP BY.` foi retornado, pois a instrução CASE, não foi informada na clausula GROUP BY

Uma forma de aplicar o AVG nesta consulta, é buscar a média de preço dos produtos por classificação, ou seja, será retornado a média aritmética de todos os produtos classificados como barato, de todos os produtos classificados como em conta e de produtos classificados como caro:

SELECT 
CASE WHEN [PREÇO DE LISTA] >= 12 THEN 'PRODUTO CARO'
WHEN [PREÇO DE LISTA] >= 7 AND [PREÇO DE LISTA] < 12 THEN 'PRODUTO EM CONTA'
ELSE 'PRODUTO BARATO' END AS 'CLASSIFICAÇÃO',
AVG([PREÇO DE LISTA]) as 'Média'
FROM
[TABELA DE PRODUTOS]
GROUP BY CASE WHEN [PREÇO DE LISTA] >= 12 THEN 'PRODUTO CARO'
WHEN [PREÇO DE LISTA] >= 7 AND [PREÇO DE LISTA] < 12 THEN 'PRODUTO EM CONTA'
ELSE 'PRODUTO BARATO' END

Print da tela do SSMS onde o comando SQL anterior está sendo executado, e o resultado retornado é a média aritmética do preço dos produtos por classificação, produto barato, em conta e caro.

Qualquer nova dúvida é só falar e bons estudos!

Boa noite Danielle,

Houve uma falta de informação minha na pergunta.

Assim, o professor faz o select com a tabela nome_produto, usa o case para fazer a condição e no final no group by o professor leva a tabela nome_produto, mais a condição case.

A minha duvida é: dentro do case ele utiliza a tabela preço de lista, em vez de eu levar todo o case para o group by eu não poderia levar somente as tabelas nome_produto e preço_de_lista ou sim eu preciso levar toda a condição case?

solução!

Olá Vinicius!

Você pode sim utilizar apenas o campo[PREÇO DE LISTA] que faz parte da instrução CASE.

Ao utilizarmos uma função de agregação, normalmente também precisamos informar a cláusula group by, que é utilizada para agrupar registros semelhantes de uma tabela em um ou mais campos. No SQL Server não é permitido realizar consultas onde os campos listados na seleção que não estão em uma função de agregação, não estão informadas na cláusula group by.

Como no exemplo utilizado pelo instrutor, na seleção temos o campo [NOME DO PRODUTO], a instrução CASE e o campo AVG([PREÇO DE LISTA]) que está dentro da função de agregação AVG, neste caso, precisamos informar na cláusula group by, todos os campos que não fazem parte da função de agregação, ou seja, o campo [NOME DO PRODUTO] a instrução CASE ou o campo [PREÇO DE LISTA] que faz parte da instrução CASE, precisam ser informados na cláusula group by, caso contrário, um erro será retornado.

Espero ter ajudado e bons estudos!