2017-11-01 2 views
1

ich folgende Daten haben:kumulative Summe mit dem Wert zurückgesetzt und Resum dann

lbid | lbdate  | lbtype  | lbamount 
-----+------------+---------------+--------- 
    1 | 2017-11-01 | Add Plafon |  20 
    2 | 2017-11-02 | Use Balance |  5 
    3 | 2017-11-03 | Add Balance |  1 
    4 | 2017-11-04 | Reduce Plafon |  10 
    5 | 2017-11-06 | Use Balance |  8 
    6 | 2017-11-07 | Add Balance |  2 
    7 | 2017-11-08 | Reduce Plafon |  5 
    8 | 2017-11-10 | Add Plafon |  10 
    9 | 2017-11-11 | Use Balance |  1 
    10 | 2017-11-12 | Reduce Plafon |  5 

Im Grunde ist das Endergebnis ich so aussehen erwarten:

lbid | lbdate  | lbtype  | lbamount | sumplafon | sumbalance 
-----+------------+---------------+-----------+-----------+------------- 
    1 | 2017-11-01 | Add Plafon |  20 |  20 |  20 
    2 | 2017-11-02 | Use Balance |  5 |  20 |  15 
    3 | 2017-11-03 | Add Balance |  1 |  20 |  16 
    4 | 2017-11-04 | Reduce Plafon |  10 |  10 |  10 
    5 | 2017-11-06 | Use Balance |  8 |  10 |   2 
    6 | 2017-11-07 | Add Balance |  2 |  10 |   4 
    7 | 2017-11-08 | Reduce Plafon |  5 |  5 |   4 
    8 | 2017-11-10 | Add Plafon |  10 |  15 |  14 
    9 | 2017-11-11 | Use Balance |  1 |  15 |  15 
    10 | 2017-11-12 | Reduce Plafon |  5 |  10 |  10 

sumplafon Summe aller lbamount ist die lbtype hinzufügen Balance (positiv) und Reduce Balance (negativ, um das Somplafon zu subtrahieren).

Ich habe es bereits getan, indem ich das getan habe.

sum(
    case 
     when "lbtype" = 'Add Plafon' then "lbamount" 
     when "lbtype" = 'Reduce Plafon' then -1 * "lbamount" 
     else 0 
    end 
) over (order by "lbdate") sumplafon 

Und die sumbalance ist Summe aller lbamount die lbtype sind hinzufügen Plafon (postive), Verwenden Balance (postive), Verwenden Balance (negativ), aber jedes Mal Plafon lbtype reduzieren gefunden wird, wird die sumbalance zurückgesetzt zu summplafon, wenn die sumbalance größer als summplafon ist.

Zum Beispiel lbid 4 welches lbtyp ist Reduzieren Plafon, die Summanz ist 16 und es ist größer als summplafon 10, deshalb muss die Summbalance auf ihr summplafon, das 10 ist, zurückgesetzt werden und dann wieder die kumulative Summe der Summbalance .

Ich habe es versucht, indem ich die Gruppe von zuerst in cte mit count so vorbereitet.

count(
    case when "lbtype" = 'Reduce Plafon' then 1 else null end 
) over (order by "lbdate") countplafon 

Und dann in der zweiten CTE I Summe Partition in der ersten CTE des countplafon unter Verwendung tat, wie folgt aus:

sum(
    case 
     when "lbtype" = 'Add Plafon' or "lbtype" = 'Add Balance' then "lbamount" 
     when "lbtype" = 'Use Balance' then -1 * "lbamount" 
     else 0 
    end 
) over (partition by "countplafon" order by "lbdate") sumbalance 

Aber das Ergebnis Zurücksetzen wird nur die sumbalance von Anfang an, weil es verwendet Gruppe von countplafon.

lbid | lbdate  | lbtype  | lbamount | countplafon |sumplafon | sumbalance 
-----+------------+---------------+-----------+-----------+-------------|----------- 
    1 | 2017-11-01 | Add Plafon |  20 |   0 |  20 |  20 
    2 | 2017-11-02 | Use Balance |  5 |   0 |  20 |  15 
    3 | 2017-11-03 | Add Balance |  1 |   0 |  20 |  16 
    4 | 2017-11-04 | Reduce Plafon |  10 |   1 |  20 |   0 
    5 | 2017-11-06 | Use Balance |  8 |   1 |  20 |  -8 
    6 | 2017-11-07 | Add Balance |  2 |   1 |  20 |  -6 
    7 | 2017-11-08 | Reduce Plafon |  5 |   2 |  20 |   0 
    8 | 2017-11-10 | Add Plafon |  10 |   2 |  20 |  10 
    9 | 2017-11-11 | Use Balance |  1 |   2 |  20 |   9 
    10 | 2017-11-12 | Reduce Plafon |  5 |   3 |  20 |   0 

Hier ist die sqlfiddle.

Hier ist der Sql.

with 
    cte_runningnumbers1 
    as (
     select 
      "lbid", 
      "lbdate", 
      "lbtype", 
      "lbamount", 
      count(
       case when "lbtype" = 'Reduce Plafon' then 1 else null end 
      ) over (order by "lbdate") countplafon, 
      sum(
       case 
        when "lbtype" = 'Add Plafon' then "lbamount" 
        when "lbtype" = 'Reduce Plafon' then -1 * "lbamount" 
        else 0 
       end 
      ) over (order by "lbdate") sumplafon 
     from "lb" 
    ), 
    cte_runningnumbers2 as (
     select 
      *, 
      sum(
       case 
        when "lbtype" = 'Add Plafon' or "lbtype" = 'Add Balance' then "lbamount" 
        when "lbtype" = 'Use Balance' then -1 * "lbamount" 
        else 0 
       end 
      ) over (partition by "countplafon" order by "lbdate") sumbalance 
     from "cte_runningnumbers1" 
    ) 
select * 
from cte_runningnumbers2 

Ich war nach diesem SO question, aber ich bin immer noch verwirren, wie mein Problem zu lösen.

Der letzte Schritt, den ich tun muss, ist es mit der vorherigen Sumbalance oder summplafon hinzuzufügen (wenn die Sumbalance größer als sumplafon ist), aber ich weiß nicht, wie es geht. Kann mir jemand helfen?

Antwort

1

Erstellen eines custom aggregate function. Platz die Logik in einem Funktionszustandsübergang:

create or replace function lb_agg_fun(sumbalance numeric, lbtype text, lbamount numeric) 
returns numeric language sql as $$ 
    select case 
     when lbtype in ('Add Plafon', 'Add Balance') then sumbalance + lbamount 
     when lbtype = 'Use Balance' then sumbalance - lbamount 
     else case 
      when lbamount < sumbalance then lbamount 
      else sumbalance 
     end 
    end; 
$$; 

Create an aggregate:

create aggregate lb_agg(text, numeric) (
    sfunc = lb_agg_fun, 
    stype = numeric, 
    initcond = 0 
); 

Und es verwenden:

select *, lb_agg(lbtype, lbamount) over (order by lbdate) as sumbalance 
from lb; 

lbid | lbdate | lbtype  | lbamount | sumbalance 
------+------------+---------------+----------+------------ 
    1 | 2017-11-01 | Add Plafon |  20 |   20 
    2 | 2017-11-02 | Use Balance |  5 |   15 
    3 | 2017-11-03 | Add Balance |  1 |   16 
    4 | 2017-11-04 | Reduce Plafon |  10 |   10 
    5 | 2017-11-06 | Use Balance |  8 |   2 
    6 | 2017-11-07 | Add Balance |  2 |   4 
    7 | 2017-11-08 | Reduce Plafon |  5 |   4 
    8 | 2017-11-10 | Add Plafon |  10 |   14 
    9 | 2017-11-11 | Use Balance |  1 |   13 
    10 | 2017-11-12 | Reduce Plafon |  5 |   5 
(10 rows)