2013/10/30 Ramiro Pamponet <[email protected]>
> Bom dia Pessoal,
>
> utilizo a seguinte query abaixo para montar um relatório no iReport para
> meu programa ...
>
> -------------------------------------------------------------------------------------------------------------
> select distinct unidade, estado, extract(year from data) as ano,
> extract(month from data) as mes, sum(vendas) as atendimentos from(
> select distinct nom_filial as unidade, est_filial as estado, (dat_emissao)
> as data, count(dat_emissao) as vendas
> from cadcvend, cadfilia
> where cadfilia.cod_filial = cadcvend.cod_filial
> and flg_excluido is null
> and num_nf is null
> and extract(year from dat_emissao) between $P{ano_ini} and $P{ano_fim}
> and extract(month from dat_emissao) between $P{mes_ini} and $P{mes_fim}
> group by dat_emissao, nom_filial, est_filial order by dat_emissao) as
> registro
> where extract(year from data) between $P{ano_ini} and $P{ano_fim}
> and extract(month from data) between $P{mes_ini} and $P{mes_fim}
> group by extract(year from data), extract(month from data), unidade, estado
> order by extract(year from data), extract(month from data)
>
> -------------------------------------------------------------------------------------------------------------
> ... onde os parâmetros $P{ano_ini}, $P{ano_fim}, $P{mes_ini} e $P{mes_fim}
> são passados pelo programa com DOUBLE e na configuração dos parâmetros no
> relatório eu os declaro assim - new Double(valor).
>
> O relatório funciona perfeitamente, se for considerado um período entre os
> meses de 1 a 12 dentro do mesmo ano ou se for considerado todos os meses de
> vários anos, mesmo o ano não tendo acabado ainda.
>
> Para minha surpresa, estava realizando alguns teste no programa e percebi
> o seguinte bug: considerando o mês inicial = 1, o ano inicial = 2005, o mês
> final = 5 e o ano final = 2006 (por exemplo), o relatório rea montado da
> seguinte forma ...
>
> Ano Mês Atendimentos
> 2005 1 xxx
> 2005 2 xxx
> 2005 3 xxx
> 2005 4 xxx
> 2005 5 xxx
> 2006 1 xxx
> 2006 2 xxx
> 2006 3 xxx
> 2006 4 xxx
> 2006 5 xxx
>
> ... pulando os meses 6 a 12 do ano de 2005 (por exemplo).
>
>
O seu erro nesse caso é considerar a parte de mês - EXTRACT(MONTH FROM
data) - e ano - EXTRACT(YEAR FROM data) - de forma independente, e não
uni-los numa mesma verificação.
> Em um fórum do GUJ fui orientado a modificar minha query da seguinte forma
> ...
>
> -------------------------------------------------------------------------------------------------------------
> select distinct unidade, estado, extract(year from data) as ano,
> extract(month from data) as mes, sum(vendas) as atendimentos from(
> select distinct nom_filial as unidade, est_filial as estado, (dat_emissao)
> as data, count(dat_emissao) as vendas
> from cadcvend, cadfilia
> where cadfilia.cod_filial = cadcvend.cod_filial
> and flg_excluido is null
> and num_nf is null
> and extract(year from dat_emissao) || extract(month from dat_emissao)
> between $P{ano_ini} || $P{mes_ini} and $P{ano_fim} || $P{mes_fim}
> group by dat_emissao, nom_filial, est_filial order by dat_emissao) as
> registro
> where extract(year from dat_emissao) || extract(month from dat_emissao)
> between $P{ano_ini} || $P{mes_ini} and $P{ano_fim} || $P{mes_fim}
> group by extract(year from data), extract(month from data), unidade, estado
> order by extract(year from data), extract(month from data)
>
> -------------------------------------------------------------------------------------------------------------
> ... que resolveu meu problema em parte, pois dessa forma pega todos os
> meses do intervalo de ano selecionado, mas no último ano, se ainda não
> tiver sido concluído (exemplo 2013) ele pega apenas o 1º e o último mês do
> intervalo, pulando todos os outros meses do ano, mas se considerar apenas o
> ano de 2013 e os meses de 1 a 10, o relatório sai correto, ou se considerar
> apenas anos que já foram concluídos, ou então, sempre considerar o mês
> inicial = 1 e o mês final = 12.
>
>
Nesse caso solucionaria o problema que citei, mas agora você gerou outro
problema, está concatenando campos do tipo inteiro, o que significa que
resultaram num tipo texto (string), daí as verificações de ordenação e no
BETWEEN irão considerar a ordem alfabética, por exemplo, a Fevereiro de
2013 vem antes (é menor) que Novembro de 2013, mas se considerarmos a
concatenação de strings, teremos '20132' para Fevereiro e '201311' para
Novembro, daí se ordenarmos alfabeticamente vamos ter que Fevereiro depois
(maior que) de Novembro.
> Existe alguma forma de juntar o que está dando certo no 1º relatório com o
> que está dando certo no 2º relatório?
>
> As sugestões serão bem vidas!
>
>
Quanto às soluções, temos infinitas, uma delas é adicionar um 0 para os
meses menores que Outubro (10), por exemplo, Fevereiro de 2013 ficaria
'201302' e não '20132'. Para gerar a string dessa forma, podemos usar a
função to_char:
select distinct unidade, estado, extract(year from data) as ano,
extract(month from data) as mes, sum(vendas) as atendimentos
from(
select distinct nom_filial as unidade, est_filial as estado, (dat_emissao)
as data, count(dat_emissao) as vendas
from cadcvend, cadfilia
where cadfilia.cod_filial = cadcvend.cod_filial
and flg_excluido is null
and num_nf is null
and to_char(CAST(dat_emissao AS timestamp), 'YYYYMM')
between to_char($P{ano_ini}, '0000') || to_char($P{mes_ini}, '00')
and to_char($P{ano_fim}, '0000') || to_char($P{mes_fim}, '00')
group by dat_emissao, nom_filial, est_filial order by dat_emissao
) as registro
where to_char(CAST(dat_emissao AS timestamp), 'YYYYMM')
between to_char($P{ano_ini}, '0000') || to_char($P{mes_ini}, '00')
and to_char($P{ano_fim}, '0000') || to_char($P{mes_fim}, '00')
group by extract(year from data), extract(month from data), unidade, estado
order by extract(year from data), extract(month from data)
Outra possível solução seria usando o date_trunc, mas a acima me parece
mais simples e eficaz.
> Obrigado aos que puderem me dar essa ajuda
>
>
Sussa.
PS: Não analisei sua consulta inteira (só foquei nos filtros de data), mas
tem certeza que precisa dessa sub-consulta aí? Parece que podia fazer
direto.
Abraços.
--
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral