我正在尝试从以下包含交易的postgresql表计算银行帐户的每月余额:
# \d transactions
View "public.transactions"
Column | Type | Collation | Nullable | Default
--------+------------------+-----------+----------+---------
year | double precision | | |
month | double precision | | |
bank | text | | |
amount | numeric | | |
在“累计金额”中,我的意思是该金额应包含从时间开始到给定月末为止的所有交易的总和,而不仅仅是给定月份的所有交易。
我想到了以下查询:
select
a.year, a.month, a.bank,
(select sum(b.amount) from transactions b
where b.year < a.year
or (b.year = a.year and b.month <= a.month))
from
transactions a
order by
bank, year, month;
问题在于,每个银行每个月包含的行数与那里的交易数一样多。如果更多,那么更多,如果没有,则没有。 我想要一个查询,其中在整个时间间隔(包括第一笔和最后一笔交易)中,每个银行和每个月正好包含一行。
该怎么做?
在https://rextester.com/WJP53830上可以找到示例数据集和查询,这是@a_horse_with_no_name
提供的。答案 0 :(得分:2)
您需要先生成一个月列表,然后才能将交易表外部连接到该列表。
with all_years as (
select y.year, m.month, b.bank
from generate_series(2010, 2019) as y(year) --<< adjust here for your desired range of years
cross join generate_series(1,12) as m(month)
cross join (select distinct bank from transactions) as b(bank)
)
select ay.*, sum(amount) over (partition by ay.bank order by ay.year, ay.month)
from all_years ay
left join transactions t on (ay.year, ay.month, ay.bank) = (t.year::int, t.month::int, t.bank)
order by bank, year, month;
与所有银行的交叉连接是必要的,因此all_years
CTE还将在每个月的行中包含一个银行。
答案 1 :(得分:0)
这是我在Oracle 10 SQL中的建议:
select a.year,a.month,a.bank, (select sum(b.amount) from
(select a.year as year,a.month as month,a.bank as bank,
sum(a.amount) as amount from transactions c
group by a.year,a.month,a.bank
) b
where b.year<a.year or (b.year=a.year and b.month<=a.month))
from transactions a order by bank, year, month;
答案 2 :(得分:0)
请考虑先按银行和月份汇总所有交易,然后运行窗口shirt_walk
,以滚动自最早金额起的每月金额。
SUM() OVER()
如果要获得年初至今的总和,请通过将年份加到分区来调整WITH agg AS (
SELECT t.year, t.month, t.bank, SUM(t.amount) AS Sum_Amount
FROM transactions t
GROUP BY t.year, t.month, t.bank
)
SELECT agg.year, agg.month, agg.bank,
SUM(agg.Sum_Amount) OVER (PARTITION BY agg.bank ORDER BY agg.year, agg.month) AS rolling_sum
FROM agg
ORDER BY agg.year, agg.month, agg.bank
子句:
OVER()