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 »

Resolvi
2020-12-18 17_42_06-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 »

Como tratar null? apesar de usar IFNULL não funcionou tentei também COALESCE
2020-12-18 18_04_25-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 »

Nada como um SELECT por cima pra resolver o mais interno
2020-12-18 18_21_42-Window.png

Código: Selecionar todos

SELECT X.MES, IFNULL(X.TOTAL,0) FROM (
WITH RECURSIVE Ano AS (
 SELECT 1 AS mes
 UNION
 SELECT mes + 1 AS mes
 FROM Ano
   WHERE
    Ano.mes < 12
) 
SELECT * FROM Ano
LEFT JOIN 
( SELECT D_VENC AS VENCIMENTO, Sum( apa.vl_guia) AS TOTAL, YEAR(D_VENC) AS ANO 
  FROM cobrancauti APA
  WHERE
  APA.D_PGTO IS NULL AND
  YEAR( APA.D_VENC )  = 2018
  GROUP BY 
  MONTH( APA.D_VENC )
 ) AS B ON ANO.MES = MONTH( B.VENCIMENTO )

ORDER BY MES ) X
ORDER BY X.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)
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 »

Usou recursive e CTE ao mesmo tempo, ou isso já tinha antes?

Tem aquela função de trazer zerado, que não lembro qual era, que acho que tem neste post.
Revi o post: COALESCE()

COALESCE( a, b, c, d, e, f, 0 )

Retorna o primeiro válido, que não seja NULL.
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 »

Para um ano ok, mas para 3 anos, 2018 a 2020, USEI UM BETWEEN mas o resultado ficou errado
2020-12-18 18_42_43-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 »

JoséQuintas escreveu:Usou recursive e CTE ao mesmo tempo, ou isso já tinha antes?
Usei o exemplo do Alexandre, tomei uma surra pra entender mas consegui fazer funcionar, agora o problema é para um período maior por ano
►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:Executando essa seleção dá erro
Sim. A seleção está incompleta. A definição de um CTE termina com um ou mais comandos DML (Data Management Language) ou seja, SELECT, INSERT, UPDATE ou DELETE.

Como você precisa selecionar mais de um ano e dentro de cada ano o mês se repete, no JOIN é preciso considerar o ano também...

Modifiquei o CTE para gerar os 36 meses dos anos que vi no teu código (2018,2019 e 2020). Juntei a este novo CTE o código que você postou. Como não tenho as tuas tabelas, não consegui testar. Mas acho que falta pouco. Acho que o caminho é este. Teste o código abaixo e faça as correções necessárias.

Código: Selecionar todos

WITH recursive Datas AS (
  -- "Membro Âncora"
  SELECT
    1 AS Mes,
    2018 AS Ano,
    1 as Loops
  UNION ALL
    -- "Membro Recursivo"
  SELECT
    CASE
      WHEN Loops % 12 = 0 THEN 1
      ELSE Mes + 1
    end,
    CASE
      WHEN Loops % 12 = 0 THEN Ano + 1
      ELSE Ano
    end,
    Loops + 1
  FROM Datas  /* Resultado da última iteração */
  WHERE
    Loops < 36
)
SELECT  *
  FROM (
      SELECT
        D_VENC AS VENCIMENTO,
        Coalesce(Sum(apa.vl_guia), 0) AS TOTAL,
        Coalesce(Month(D_VENC), Datas.Mes) AS MES,
        Coalesce(YEAR(D_VENC), Datas.Ano) AS ANO
      FROM cobrancauti APA
      WHERE
        APA.D_PGTO IS NULL
        AND YEAR(APA.D_VENC) BETWEEN 2018
        AND 2020
      GROUP BY
        MONTH(APA.D_VENC) )
      AS b
  LEFT JOIN ( SELECT Mes, Ano 
                FROM Datas 
            ORDER BY Ano, Mes ) AS d 
    ON d.Mes = MONTH(B.VENCIMENTO)
   AND d.Ano = Year(B.VENCIMENTO)
ORDER BY
  b.MES
O CTE eu consigo testar e está funcionando.
CTE.JPG
Recursive Common Table Expression CTE
[]´s
Alexandre Santos (AlxSts)
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 »

2020-12-19 13_49_15-Window.png
Alexandre, deu esse erro
►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 »

2020-12-19 13_55_22-Window.png
Coloquei NULL para funcionar

Coalesce(Month(D_VENC),null) AS MES,
Coalesce(YEAR(D_VENC), null) AS ANO

Mas o resultado sumarizou os 3 anos em um único ano 2018
►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 »

Acrescentei MONTH(apa.d_venc) ) no Group By

GROUP BY
year(APA.D_VENC), MONTH(apa.d_venc) )

Mas o resultado para os meses 4 e 9 e 10 de janeiro não sairam na lista com 0,00
Teve mês que teve pagamento ABRIL, SETEMBRO E OUTUBO e não sairam na lista com 0,00
Eles tem que aparecer mesmo com 0,00 se não o Gráfico não funciona

APA.D_PGTO IS NULL aqui que é problema, nessa query se no teve pagamento deveria aparacer com 0,00
2020-12-19 14_18_34-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 »

Esse aqui fez, mas para um ano, se colocar BETWEEN 2018 AND 2020 não funciona

Código: Selecionar todos

SELECT X.ANO, X.MES AS MES, IFNULL(X.TOTAL,0) AS TOTAL FROM (
WITH RECURSIVE Ano AS (
 SELECT 1 AS MES
 UNION 
 SELECT MES + 1 AS MES
 FROM ANO
   WHERE
    Ano.mes < 12
) 
SELECT * FROM ANO
LEFT JOIN 
( SELECT D_VENC AS VENCIMENTO, Sum( apa.vl_guia) AS TOTAL, YEAR(D_VENC) AS ANO 
  FROM cobrancauti APA
  WHERE
  APA.D_PGTO IS NULL AND
  YEAR( APA.D_VENC ) = 2018
  GROUP BY 
  YEAR( APA.D_VENC ), MONTH( APA.D_VENC )
 ) AS B ON ANO.MES = MONTH( B.VENCIMENTO ) 
ORDER BY MES ) X
ORDER BY  X.MES 
2020-12-19 14_39_04-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á!
Ali onde você trocou Datas por NULL o certo é d.mes e d.ano.
Fica difícil sem os dados. Não consegue anexar as estruturas das tabelas com alguns dados?
[]´s
Alexandre Santos (AlxSts)
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 »

Inverti o LEFT JOIN agora funcionou

Código: Selecionar todos

WITH recursive Datas AS (
  -- "Membro Âncora"
  SELECT
    1 AS Mes,
    2018 AS Ano,
    1 as Loops
  UNION ALL
    -- "Membro Recursivo"
  SELECT
    CASE
      WHEN Loops % 12 = 0 THEN 1
      ELSE Mes + 1
    end,
    CASE
      WHEN Loops % 12 = 0 THEN Ano + 1
      ELSE Ano
    end,
    Loops + 1
  FROM Datas  /* Resultado da última iteração */
  WHERE
    Loops < 36
)
SELECT  *
  FROM 
  Datas D
  LEFT JOIN
  (
      SELECT
        D_VENC AS VENCIMENTO,
        Coalesce(Sum(apa.vl_guia), 0) AS TOTAL,
        Coalesce(Month(D_VENC),null) AS MES,
        Coalesce(YEAR(D_VENC), null) AS ANO
      FROM cobrancauti APA
      WHERE
        APA.D_PGTO IS NULL
        AND YEAR(APA.D_VENC) BETWEEN 2018
        AND 2020 
       GROUP BY
        year(APA.D_VENC), MONTH(apa.d_venc) ) AS RES ON RES.ANO = D.ANO AND RES.MES  = D.MES
2020-12-19 14_56_16-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á!

Show!!! Se trocar aqueles NULL por d.mes e d.ano acho que melhora.
[]´s
Alexandre Santos (AlxSts)
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 »

Obrigado Alexandre e Quintas pelas dicas,

Alexandre muito legal esse recurso RECURSIVE, funcionou perfeito

Já removi a GAMBI do código, RS
►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