Select com agrupamento

Forum sobre SQL.

Moderador: Moderadores

Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

Pessoal,

Preciso de uma ajuda no retorno de um select com agrupamento, esse select retorna valor por mês usando filtro, acontece que tem mês nesse exemplo que não aparece na sequência,
Na imagem é o mês 4 não tem informação, nesse caso eu queria que ele apareça com valor zero 0,00, a não ser que tenha um tratamento a função que Quintas me passou:

Código: Selecionar todos


   aDados := { {}, {}, {} }

   FOR EACH oElemento in aDadosCob
      IF oElemento[ "ANO" ] = Year( Date() ) - 2
         nIndice := 1
      ELSEIF oElemento[ "ANO" ] = Year( Date() ) - 1
         nIndice := 2
      ELSE
         nIndice := 3
      ENDIF
      
      aAdd( aDados[ nIndice ], oElemento[ "VALOR" ]  )
         
   NEXT
2020-12-17 16_06_52-Window.png
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Select com agrupamento

Mensagem por alxsts »

Olá!

Experimente Trocar o INNER JOIN pelo LEFT JOIN. Trate o NULL em cada coluna. Exemplo: troque Sum(...) por Coalesce( Sum( apa.vl_guia ),0 ) As Valor
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select com agrupamento

Mensagem por JoséQuintas »

Se não encontrar outro jeito, uma possibilidade seria criar os meses e usar no select

SELECT ( 1 AS MES, 2 AS MES, 3 AS MES, 4 AS MES, 5 AS MES, 6 AS MES, 7 AS MES ... ) AS MESES

De repente, ter uma tabela de meses com descrição, pra já vir pronto.... quem sabe....
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

O que remove o mês é o filtro no where APA.D_PGTO IS NULL
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

alxsts escreveu:Olá!

Experimente Trocar o INNER JOIN pelo LEFT JOIN. Trate o NULL em cada coluna. Exemplo: troque Sum(...) por Coalesce( Sum( apa.vl_guia ),0 ) As Valor
Não deu certo
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select com agrupamento

Mensagem por JoséQuintas »

Me veio na cabeça colocar IF pra somar zero quando NULL, mas pode deixar muito mais demorado porque vai processar tudo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select com agrupamento

Mensagem por JoséQuintas »

Código: Selecionar todos

SELECT

A.MES, B.VALOR, B.ANO

FROM

( 1 AS MES, 2 AS MES, 3 AS MES, 4 AS MES, 5 AS MES, 6 AS MES, 
7 AS MES, 8 AS MES, 9 AS MES, 10 AS MES, 11 AS MES, 12 AS MES ) AS A

LEFT JOIN 

( SEU SELECT ) AS B ON A.MES = B.MES

ORDER BY MES
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

qUINTAS,

De erro de sintaxe aqui

( 1 AS MES, 2 AS MES, 3 AS MES, 4 AS MES, 5 AS MES, 6 AS MES,
7 AS MES, 8 AS MES, 9 AS MES, 10 AS MES, 11 AS MES, 12 AS MES ) AS A

Estou usando MariaDb
2020-12-17 21_10_54-Window.png
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

Fiz uma gambi até descobrir como resolver no select, se não acha o mês adiciona ele na HT, assim faz a RmChar funcionar com os 12 meses

Código: Selecionar todos

  FOR EACH oElemento IN aDadosCob
   
      IF oElemento["ANO"] = Year( Date() ) - 2
         FOR I:=1 TO 12
            nSearch := Hb_aScan( aDadosCob, {|o| o["MES"] = I .AND. o["ANO"] = Year( Date() ) - 2 })
            IF nSearch = 0
               hRecord := {=>}
               hRecord["TOTAL"] := 0.00
               hRecord["MES"]   := I
               hRecord["VALOR"] := 0.00
               hRecord["ANO"]   := Year( Date() ) - 2
               aAdd( aDadosCob, hRecord )
            ENDIF
         NEXT
      ENDIF
      *
      IF oElemento["ANO"] = Year( Date() ) - 1
         FOR I:=1 TO 12
            nSearch := Hb_aScan( aDadosCob, {|o| o["MES"] = I .AND. o["ANO"] = Year( Date() ) - 1 })
            IF nSearch = 0
               hRecord := {=>}
               hRecord["TOTAL"] := 0.00
               hRecord["MES"]   := I
               hRecord["VALOR"] := 0.00
               hRecord["ANO"]   := Year( Date() ) - 1
               aAdd( aDadosCob, hRecord )
            ENDIF
         NEXT
      ENDIF
      *
      IF oElemento["ANO"] = Year( Date() )
         FOR I:=1 TO 12
            nSearch := Hb_aScan( aDadosCob, {|o| o["MES"] = I .AND. o["ANO"] = Year( Date() ) })
            IF nSearch = 0
               hRecord := {=>}
               hRecord["TOTAL"] := 0.00
               hRecord["MES"]   := I
               hRecord["VALOR"] := 0.00
               hRecord["ANO"]   := Year( Date() )
               aAdd( aDadosCob, hRecord )
            ENDIF
         NEXT
      ENDIF
   NEXT
   
   aSort( aDadosCob ,,, {|x,y| StrZero( y["ANO"], 4 ) + ;
   	                           StrZero( y["MES"], 2 ) > ;
   	                           StrZero( x["ANO"], 4 ) + ;
   	                           StrZero( x["MES"], 2 ) } )
2020-12-17 23_47_50-Greenshot.png
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Select com agrupamento

Mensagem por alxsts »

Olá!
asimoes escreveu:De erro de sintaxe aqui
A sintaxe está errada. Tente assim:

Código: Selecionar todos

select
  *
from (
    select 0 as Mes
    union
    select 1
    union
    select 2
    union
    select 3
    union
    select 4
    union
    select 5
    union
    select 6
    union
    select 7
    union
    select 8
    union
    select 9
    ...
    union
    select 12
  ) As A;
Usando CTE (Common Table Expressions) recursivos
CTEs recursivos estão disponíveis no MySQL 8.0, MariaDB 10.2 e posteriores

Não tenho nem MySQL nem MariaDB. Teste/ajuste o código abaixo:

Código: Selecionar todos

WITH RECURSIVE Ano AS (
  SELECT
    1 AS mes
  UNION ALL
  SELECT
    mes + 1 AS mes
  FROM Ano
  WHERE
    Ano.mes <= 12
)
SELECT
  ano.mes,
  b.valor,
  b.ano
FROM (
    SELECT
      month(apa.d_venc) as mes,
      sum(apa.vl_guia) as valor,
      year(apa.d_venc) as ano
    FROM CobrancaUti apa
  ) as b ON ano.mes = b.mes
ORDER BY
  b.mes
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Select com agrupamento

Mensagem por JoséQuintas »

alxsts escreveu:A sintaxe está errada
Realmente: do jeito que eu fiz é como se estivesse selecionando 12 campos, e não 12 registros.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

Ainda não foi,
2020-12-18 09_41_48-Window.png
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

Executando essa seleção dá erro
2020-12-18 09_48_32-Window.png
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

Essa forma funciona, mas como funcionar no que eu preciso?
2020-12-18 10_00_08-Window.png
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Select com agrupamento

Mensagem por asimoes »

Consegui usar a sintaxe RECURSIVE mas não reso0lveu o problema, o que esperava é que os mese 4 e 9 desse exemplo viessem com valor null ou zero
2020-12-18 17_00_36-Window.png

Código: Selecionar todos

WITH RECURSIVE Ano AS (
 SELECT 1 AS mes, B.MES
 UNION ALL
 SELECT mes + 1 AS mes
 FROM Ano
 WHERE
    Ano.mes <= 12
) 

SELECT
  B.*
FROM (
    SELECT
      year(apa.d_venc) as ano,
      month(apa.d_venc) as mes,
      SUM( apa.vl_guia )
    FROM CobrancaUti apa
      where
      YEAR( D_VENC) = 2018 AND
      APA.D_PGTO IS NULL AND 
      month(apa.d_venc) <= 12
     GROUP BY YEAR( D_VENC), MONTH( D_VENC)  
  ) as b 
  
ORDER BY
ANO, mes 
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Responder