我有以下数据:
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
基本上,我期望的最终结果是这样的:
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是lbtype为Add Balance(正)和Reduce Balance(负)的所有lbamount的总和。
我已经这样做了。
sum(
case
when "lbtype" = 'Add Plafon' then "lbamount"
when "lbtype" = 'Reduce Plafon' then -1 * "lbamount"
else 0
end
) over (order by "lbdate") sumplafon
而sumballance是lbtype为Add Plafon(positive)、Use Balance(positive)、Use Balance(negative)的所有lbamount的和,但是每次找到lbtype Reduce Plafon,如果sumballance大于sumplafon,sumballance将重置为sumplafon。
例如,lbtype为Reduce Plafon的lbid 4,sumballance为16,大于sumplafon 10,因此sumballance需要重置为其sumplafon为10,然后再次继续sumballance的累加和。
我试过先在cte上和伯爵这样准备小组。
count(
case when "lbtype" = 'Reduce Plafon' then 1 else null end
) over (order by "lbdate") countplafon
然后在第二个cte中,我用第一个cte中的countplafon进行了求和,如下所示:
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
但结果只是从头重置sumballance,因为它使用group by 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
这是sqlfiddle。
这是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
我一直在关注这个问题,但我仍然不知道如何解决我的问题。
我需要做的最后一步是将它与之前的sumbalance或sumplafon(如果sumbalance大于sumplafon)一起添加,但我不知道怎么做。有人能帮我吗?
最佳答案
创建custom aggregate function.将逻辑置于状态转换函数中:
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
);
使用它:
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)