duvida em select

Firebird

30/06/2010

Boa tarde,   tenho o seguinte problema:   uma tabela com os campos:   valor decimal(10,2)   data date   gostaria de fazer um totalizador por meses destes valores:   select SUM(t.valor), extract(month from data) as mes from tabela t where extract(year from data) = 2010 group by extract(month from data)   até ai tudo bem, este select vai me retornar a soma por mes do ano de 2010   agora o problema:   os meses que não possuem nenhum registro nao aparecem gostaria que aparecessem mesmo que com o valor zerado   ------------------------------------------ oq me retorna:   mes  valor 1    2 3 4
Paulo Candido

Paulo Candido

Curtidas 0

Respostas

Carlos Mazzi

Carlos Mazzi

30/06/2010

E se vc fizer um select que traga os meses que nao tem nada (sUM t.valor) where t.valor is null (ou algo do tipo) e depois fazer um UNION da select que traz os dados com os meses populados , com essa select que traz os meses sem nada (null ou zero), nao dá certo?
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

30/06/2010

pode ser também com stored procedures.

CREATE PROCEDURE TOTALMENSAL (
    ano smallint)
returns (
    mes integer,
    valor numeric(15,2))
as
declare variable mes_01 numeric(15,2);
declare variable mes_02 numeric(15,2);
declare variable mes_03 numeric(15,2);
declare variable mes_04 numeric(15,2);
declare variable mes_05 numeric(15,2);
declare variable mes_06 numeric(15,2);
declare variable mes_07 numeric(15,2);
declare variable mes_08 numeric(15,2);
declare variable mes_09 numeric(15,2);
declare variable mes_10 numeric(15,2);
declare variable mes_11 numeric(15,2);
declare variable mes_12 numeric(15,2);
begin
  mes = 1;

  select
      sum(case when extract(month from t.data)=1 then t.valor else 0 end) mes_01,
      sum(case when extract(month from t.data)=2 then t.valor else 0 end) mes_02,
      sum(case when extract(month from t.data)=3 then t.valor else 0 end) mes_03,
      sum(case when extract(month from t.data)=4 then t.valor else 0 end) mes_04,
      sum(case when extract(month from t.data)=5 then t.valor else 0 end) mes_05,
      sum(case when extract(month from t.data)=6 then t.valor else 0 end) mes_06,
      sum(case when extract(month from t.data)=7 then t.valor else 0 end) mes_07,
      sum(case when extract(month from t.data)=8 then t.valor else 0 end) mes_08,
      sum(case when extract(month from t.data)=9 then t.valor else 0 end) mes_09,
      sum(case when extract(month from t.data)=10 then t.valor else 0 end) mes_10,
      sum(case when extract(month from t.data)=11 then t.valor else 0 end) mes_11,
      sum(case when extract(month from t.data)=12 then t.valor else 0 end) mes_12
  from tabela t
  where extract(year from t.data) = :ano
  into :mes_01, :mes_02, :mes_03, :mes_04, :mes_05, :mes_06,
       :mes_07, :mes_08, :mes_09, :mes_10, :mes_11, :mes_12;

  while (mes <= 12) do
  begin
    valor = coalesce(case mes when 1 then mes_01
                              when 2 then mes_02
                              when 3 then mes_03
                              when 4 then mes_04
                              when 5 then mes_05
                              when 6 then mes_06
                              when 7 then mes_07
                              when 8 then mes_08
                              when 9 then mes_09
                              when 10 then mes_10
                              when 11 then mes_11
                              when 12 then mes_12
            end,0);

    suspend;

    mes = mes+1;
  end
end

para chamá-la você usa
SELECT * FROM TOTALMENSAL( 2010 )

essa stored procedure parece ser grande porém terá uma boa performance, pois o banco de dados será acessado apenas 1 vez e o restante da operação acontecerá somente em memória.

GOSTEI 0
POSTAR