Caro Matheus,

Mano, fantástico, funcionou perfeito, só o where que era t.id % 4 = 1, o
resto foi bala, agora deu pra entender um pouco mais sobre window
functions, vou pesquisar um pouco mais pq realmente é um recurso fantástico.

Muitíssimo obrigado pela rápida e grande ajuda.


Marco Aurélio Ventura da Silva
[email protected]
Prodata Informática e Cadastro LTDA
(33)3322-4444

Em 2 de fevereiro de 2015 13:09, Matheus de Oliveira <
[email protected]> escreveu:

>
> 2015-02-02 12:22 GMT-02:00 Marco Aurelio <[email protected]>:
>
>> select row_number() over() as id,  dt_vencto, vl_duplica from
>> receber_duplica
>> left outer join notas using(nota_id)
>> where nota_id = 114
>> order by dt_vencto
>>
>>
> Primeiro, evite usar row_number com OVER sem ORDER BY, apesar do resultado
> ser o esperado em versões atuais (sempre será), pela definição poderia ser
> inconsistente, então no seu caso use simplesmente o mesmo ORDER BY da
> consulta:
>
>     SELECT row_number() OVER(ORDER BY dt_vencto) AS id, ...
>     ...
>     ORDER BY dt_vencto;
>
>
> id;dt_vencto;vl_duplica
>> 1;"2015-02-28";0.70
>> 2;"2015-03-31";0.70
>> 3;"2015-04-30";0.70
>> 4;"2015-05-31";0.70
>> 5;"2015-06-30";0.70
>> 6;"2015-07-31";0.70
>> 7;"2015-08-31";0.70
>> 8;"2015-09-30";0.70
>> 9;"2015-10-31";0.70
>> 10;"2015-11-30";0.70
>>
>>  este número de linhas obviamente é variavel.
>>
>> Gostaria que me retornasse assim:
>>
>> dt_vencto1;vl_duplica1;  dt_vencto2;vl_duplica2;dt_vencto3;vl_duplica3
>> 1;2015-02-28;0,70;         2;2015-03-31;0,70        3;2015-04-30;0,70
>> 4;2015-05;30;0,70          etc
>>
>> quebrando em 3 conjunto de colunas;
>>
>> sei que dá pra fazer com TEMPORARY TABLES
>>
>> DROP TABLE IF EXISTS temporary_duplica;
>> CREATE TEMPORARY TABLE temporary_duplica as (
>> select row_number() over() as id,  dt_vencto, vl_duplica from
>> receber_duplica
>> left outer join notas using(nota_id)
>> where nota_id = 114
>> order by dt_vencto
>> );
>>
>>
>> select * from (select * from temporary_duplica where id%4=1) as a
>> left outer join(select * from temporary_duplica where id%4=2) as b on
>> a.id+1 = b.id
>> left outer join(select * from temporary_duplica where id%4=3) as c on
>> a.id+2 = c.id
>> left outer join(select * from temporary_duplica where id%4=0) as d on
>> a.id+3 = d.id
>>
>> mas neste caso como uso jasper ele não reconhece estas TEMPORARY TABLEs.
>>
>>
> Nem sei o porquê você decidiu usar tabelas temporárias, até no seu exemplo
> poderia simplesmente usar Common Table Expression (CTE) com a cláusula WITH:
>
>     WITH temporary_duplica AS (
>         <consulta original>
>     )
>     SELECT * FROM ...;
>
>
>> E sei que daria pra fazer tb, repetindo a query várias vezes, mas
>> gostaria de saber se tem como com windows functions obter estes resultados.
>>
>
> Bom, agora das melhores soluções eu vejo o uso da WINDOW FUNCTION lead ou
> usando a função crosstab da extensão tablefunc [1].
>
> A função "lead" o valor da próxima linha, o da linha após "N" valores onde
> N é o segundo parâmetro da função. Ficaria mais ou menos (não testado)
> assim:
>
>     SELECT * FROM (
>         SELECT row_number() OVER w AS id,
>             dt_vencto AS dt_vencto1, vl_duplica AS vl_duplica1,
>             lead(dt_vencto, 1) OVER w AS dt_vencto2, lead(vl_duplica, 1)
> OVER w AS vl_duplica2,
>             lead(dt_vencto, 2) OVER w AS dt_vencto3, lead(vl_duplica, 2)
> OVER w AS vl_duplica3,
>             lead(dt_vencto, 3) OVER w AS dt_vencto4, lead(vl_duplica, 3)
> OVER w AS vl_duplica4
>         FROM receber_duplica
>         LEFT OUTER JOIN notas USING(nota_id)
>         WHERE nota_id = 114
>         WINDOW w AS (ORDER BY dt_vencto)
>         ORDER BY dt_vencto
>     ) t
>     WHERE t.id % 4 = 0
>     ORDER BY dt_vencto1;
>
> A ideia é usar a "lead" para em cada linha buscar o valor da linha, e das
> 3 próximas. Depois usar o filtro `t.id % 4 = 0` para pegar remover as
> duplicatas que serão geradas (execute só a consulta interna para conferir).
>
> Mais uma dica, como boa prática eu recomendaria você a usar apelidos
> ("alias") nas consultas.
>
> Atenciosamente,
> --
> 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
>
>
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a