Fórum duvida em select #380354
30/06/2010
0
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
Curtir tópico
+ 0
Responder
Posts
15/08/2010
Carlos Mazzi
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?
Responder
Gostei + 0
16/08/2010
Emerson Nascimento
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.
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.
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)