Página 1 de 1

SELECT com GROUP BY tem SUB-GROUP

Enviado: 08 Jun 2022 15:32
por Amparo
OLA AMIGOS

Boa tarde

utilizo MariaDB e tenho uma tabela com os seguintes dados:

Código: Selecionar todos

SACADO    EMISSAO     VALOR
10002     2022-01-06  100,0000
10002     2022-02-17  110,0000
10002     2022-03-15  120,0000
10002     2022-03-17  135,0000
10006     2022-05-20   85,0000
10012     2022-02-01  258,0000
10012     2022-03-24  180,0000
10012     2022-03-25  150,0000
10012     2022-04-08  200,0000
10012     2022-04-09  210,0000
10020     2022-02-17  121,0000
10020     2022-03-15  540,0000
Preciso fazer uma consulta e trazer o total de venda de cada sacado e a quantidade de pedido no mês, a consulta deveria sair assim:

Código: Selecionar todos

SACADO  TOTAL       MES01 MES02 MES03 MES04 MES05
10002     465,0000    1    1     2      0     0
10006      52,0000    0    0     0      0     1
10012     998,0000    0    1     2      2     0
10020     661,0000    0    1     0      0     0
Ou SEJA: totalizar o pedidos de cada sacado e mostrar quantos pedidos houve em cada mês, totalizar usando GROUP BY tudo bem a sintaxe é abaixo, mas como incluir os campos dos meses 01 a 12 nesta consulta

SELECT SACADO, SUM(VALOR) AS TOTAL FROM NFESAIDAS WHERE CANCELADA = 'F' AND NATUREZA LIKE '%VENDA%' AND EMISSAO
BETWEEN '2022-01-01' AND '2022-05-31' GROUP BY SACADO ORDER BY SACADO,EMISSAO;


grato abraço

SELECT com GROUP BY tem SUB-GROUP

Enviado: 08 Jun 2022 15:55
por JoséQuintas
Tá fazendo uma confusão simples:

Se quer totalizado por data, a data tem que entrar na lista de campos também.
pode usar LAST_DAY( EMISSAO )

Código: Selecionar todos

SELECT SACADO, LAST_DAY( EMISSAO ) AS MES, SUM( VALOR ) FROM X GROUP BY SACADO, LAST_DAY( EMISSAO )
Só estou na dúvida se usaria MES ou LAST_DAY( EMISSAO ) no GROUP BY, ou se tanto faz.

Também pode pedir em colunas, como quer, mas vamos uma coisa de cada vez.

SELECT com GROUP BY tem SUB-GROUP

Enviado: 08 Jun 2022 16:02
por JoséQuintas
Pra outra parte, costumo usar um select encima desse, mas poderia ser direto.
uso parecido com isto:

Código: Selecionar todos

SELECT SACADO, IF( MONTH( MES ) = 1, VALOR, 0 ) AS MES01, IF( MONTH( MES=2, VALOR, 0 ) AS MES02, ...
FROM
( O OUTRO SELECT )

SELECT com GROUP BY tem SUB-GROUP

Enviado: 08 Jun 2022 16:08
por JoséQuintas
Talvez dê pra usar between nas colunas e fazer direto, não testei.

Código: Selecionar todos

SELECT SACADO,
   IF( EMISSAO BETWEEN '2022-01-01' AND '2022-01-31', valor, 0 ) AS MES01,
   IF( EMISSAO BETWEEN '2022-02-01' AND '2022-02-28', valor, 0 ) AS MES02,
...
WHERE EMISSAO BETWEEN 'x' AND 'y'

SELECT com GROUP BY tem SUB-GROUP

Enviado: 08 Jun 2022 16:20
por Amparo
ola amigos

boa tarde

tudo bem Quintas

consegui descobrir a sintaxe correta: não sei se é a melhor forma mais o resultado é o que eu esperava.

Código: Selecionar todos

SELECT B.NOME AS NOME, A.SACADO AS SACADO, A.EMISSAO AS EMISSAO,  SUM(A.VALOR) AS TOTAL, COUNT(*) AS QUANTIDADE,
sum( CASE WHEN MONTH(EMISSAO)='01' then 1 ELSE '' END ) as case01,
sum( CASE WHEN MONTH(EMISSAO)='02' then 1 ELSE '' END ) as case02,
sum( CASE WHEN MONTH(EMISSAO)='03' then 1 ELSE '' END ) as case03,
sum( CASE WHEN MONTH(EMISSAO)='04' then 1 ELSE '' END ) as case04,
sum( CASE WHEN MONTH(EMISSAO)='05' then 1 ELSE '' END ) as case05
FROM NFESAIDAS AS A USE INDEX(IDX_NFESAIDAS_NUMERO) LEFT JOIN CLIENTES AS B ON(A.SACADO = B.CODIGO)
WHERE A.CANCELADA = 'F' AND A.NATUREZA LIKE '%VENDA%' AND A.EMISSAO BETWEEN '2022-01-01' AND 
'2022-05-31' GROUP BY SACADO ORDER BY B.NOME,A.EMISSAO;
value!

SELECT com GROUP BY tem SUB-GROUP

Enviado: 08 Jun 2022 18:18
por JoséQuintas
ELSE '' pode até funcionar assim, mas acho que o correto seria ELSE 0 (ZERO), ou soma 1 ou soma 0.
Não sei se faz diferença na velocidade usar CASE ou IF().

SELECT com GROUP BY tem SUB-GROUP

Enviado: 09 Jun 2022 01:04
por alxsts
Olá!

Vejam: Totais por mes

SELECT com GROUP BY tem SUB-GROUP

Enviado: 10 Jun 2022 08:06
por Amparo
ola amigos

bom dia
JoséQuintas escreveu:ELSE '' pode até funcionar assim, mas acho que o correto seria ELSE 0 (ZERO), ou soma 1 ou soma 0.
Não sei se faz diferença na velocidade usar CASE ou IF().
com relação ao ELSE acredito que assuma a seguinte expressão: se mês for = ?? soma 1 senão, não faça nada!

agora quanto ao tempo talvez aconteça o que você falou: ganhar meio segundo em uma operação não há diferença, agora se esse meio segundo for por registro ai muda de figura.

abraço

SELECT com GROUP BY tem SUB-GROUP

Enviado: 10 Jun 2022 10:05
por JoséQuintas
Amparo escreveu:com relação ao ELSE acredito que assuma a seguinte expressão: se mês for = ?? soma 1 senão, não faça nada!
Não sei se ele desconsidera, ou se tem o trabalho de converter o espaço pra zero.

Quando ao IF() no lugar do WHEN, é porque parece um fonte melhor de enxergar, só por isso.
Talvez porque seja igual no Harbour, e confunda menos.

Código: Selecionar todos

sum( CASE WHEN MONTH(EMISSAO)='01' then 1 ELSE '' END ) as case01,
sum( CASE WHEN MONTH(EMISSAO)='02' then 1 ELSE '' END ) as case02,
sum( CASE WHEN MONTH(EMISSAO)='03' then 1 ELSE '' END ) as case03,
sum( CASE WHEN MONTH(EMISSAO)='04' then 1 ELSE '' END ) as case04,
sum( CASE WHEN MONTH(EMISSAO)='05' then 1 ELSE '' END ) as case05

sum( IF( MONTH(EMISSAO)='01',1,0 ) ) as case01,
sum( IF( MONTH(EMISSAO)='02',1,0 ) ) as case02,
sum( IF( MONTH(EMISSAO)='03',1,0) ) as case03,
sum( IF( MONTH(EMISSAO)='04',1,0) ) as case04,
sum( IF( MONTH(EMISSAO)='05', 1, 0 ) ) as case05

SELECT com GROUP BY tem SUB-GROUP

Enviado: 10 Jun 2022 10:12
por JoséQuintas
Aproveitando....

no harbour/clipper:

Código: Selecionar todos

sum IF( MONTH(EMISSAO)='01',1,0 ) ), IF( MONTH(EMISSAO)='02',1,0 ) TO case01, case02
numa stored procedure:

Código: Selecionar todos

SELECT SUM( IF( MONTH(EMISSAO)='01',1,0 ) ) ), SUM( IF( MONTH(EMISSAO)='02',1,0 ) ) FROM tabela INTO case01, case02
bem parecidos.