[英]How to Track Min and Max Balance of an Account
我正在研究跟蹤銀行賬戶的最大和最小余額。 有兩個表:
AccountBalanceHistoryTable - 記錄每個月末每個賬戶的余額
TransactionTable - 這記錄了一個帳戶上發生的所有交易
我創建了以下查詢以將這兩個表放在一起以獲得運行余額,然后我將使用它來 select 中的最大和最小余額:
select
i.acct_id,
i.trnxamt,
i.date_trnx,
EXTRACT (MONTH from i.date_trnx) month_num,
EXTRACT (YEAR from i.date_trnx) as year_num,
(
j.balance + sum(i.trnxamt) over (partition by i.acct_id order by i.date_trnx ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
) as balance_calc
from
TransactionTable i
left join (
select
acct_id,
monthend_date,
balance,
row_number() over (partition by acct_id order by monthend_date) as rn
from
AccountBalanceHistoryTable
) j on i.acct_id = j.acct_id
and j.rn = 1
我使用 AccountBalanceHistoryTable 來獲取我看到記錄的一個月的最后余額(第一行),並將其作為下個月的起始余額。
因此,假設在 AccountBalanceHistoryTable 中顯示,對於帳戶 123456,8 月 31 日的余額為 100 美元。 以下僅顯示了一些示例交易以及 Balance_Calc 將計算的內容:
Acct_ID | TrnxAmnt | 日期_Trnx | 月數 | Year_num | Balance_Calc |
---|---|---|---|---|---|
123456 | -55 | 20 年 9 月 29 日 | 9 | 2020 | 45 |
123456 | 10 | 20 年 9 月 30 日 | 9 | 2020 | 55 |
123456 | 100 | 20 年 10 月 1 日 | 10 | 2020 | 155 |
123456 | 20 | 20 年 10 月 1 日 | 10 | 2020 | 175 |
我遇到的問題是,上面說的是 10 月 1 日。 在此帳戶 10 月份發生任何交易之前,期初余額為 55 美元(9 月 30 日的期末余額)。 這 55 美元實際上應該是我 10 月的最低余額,但如果我使用上表和 select 2020 年 10 月的最低和最高余額,它將給我 155 美元的最低余額和 175 美元的最高余額,因為這是僅有的兩個上述子查詢結果中顯示的記錄。
訣竅是將午夜的月末余額轉移到下個月的 1 日。
這是余額表的示例
select * from AccountBalanceHistory
where acct_id = 123456
order by monthend_date;
ACCT_ID MONTHEND_DATE BALANCE
---------- ------------------- ----------
123456 31.08.2020 00:00:00 100
123456 30.09.2020 00:00:00 55
123456 31.10.2020 00:00:00 175
和你的交易表
select * from Transaction
where acct_id = 123456
order by date_trnx;
ACCT_ID DATE_TRNX TRNXAMT
---------- ------------------- ----------
123456 29.09.2020 00:00:00 -55
123456 30.09.2020 00:00:00 10
123456 01.10.2020 00:00:00 100
123456 01.10.2020 00:00:00 20
下面的查詢聯合了這兩個來源並計算了交易月份,即下個月1 日的余額。
請注意,每一行都有它的源 BAL 或 TX - 這將用於正確排序行
with tx as (
select 'BAL' source, acct_id, monthend_date date_trnx, trunc(monthend_date+1,'MM') tx_month, balance, 0 trnxamt from AccountBalanceHistory
union all
select 'TX', acct_id, date_trnx,trunc(date_trnx,'MM') tx_month, trnxamt balance, trnxamt from Transaction
)
select *
from tx
where acct_id = 123456
order by date_trnx;
SOU ACCT_ID DATE_TRNX TX_MONTH BALANCE TRNXAMT
--- ---------- ------------------- ------------------- ---------- ----------
BAL 123456 31.08.2020 00:00:00 01.09.2020 00:00:00 100 0
TX 123456 29.09.2020 00:00:00 01.09.2020 00:00:00 -55 -55
TX 123456 30.09.2020 00:00:00 01.09.2020 00:00:00 10 10
BAL 123456 30.09.2020 00:00:00 01.10.2020 00:00:00 55 0
TX 123456 01.10.2020 00:00:00 01.10.2020 00:00:00 20 20
TX 123456 01.10.2020 00:00:00 01.10.2020 00:00:00 100 100
BAL 123456 31.10.2020 00:00:00 01.11.2020 00:00:00 175 0
列balance
包含余額或交易金額,並且在我們使用每個月的分析窗口 function (從月初到當前行)添加它之前並不是很有趣
with tx as (
select 'BAL' source, acct_id, monthend_date date_trnx, trunc(monthend_date+1,'MM') tx_month, balance, 0 trnxamt from AccountBalanceHistory
union all
select 'TX', acct_id, date_trnx,trunc(date_trnx,'MM') tx_month, trnxamt balance, trnxamt from Transaction
)
select
SOURCE, ACCT_ID, DATE_TRNX, TX_MONTH,
sum(BALANCE) over (partition by ACCT_ID,TX_MONTH order by date_trnx, decode (SOURCE,'BAL',1,'TX',2), trnxamt desc) as BALANCE,
TRNXAMT
from tx
where acct_id = 123456
order by date_trnx;
SOU ACCT_ID DATE_TRNX TX_MONTH BALANCE TRNXAMT
--- ---------- ------------------- ------------------- ---------- ----------
BAL 123456 31.08.2020 00:00:00 01.09.2020 00:00:00 100 0
TX 123456 29.09.2020 00:00:00 01.09.2020 00:00:00 45 -55
TX 123456 30.09.2020 00:00:00 01.09.2020 00:00:00 55 10
BAL 123456 30.09.2020 00:00:00 01.10.2020 00:00:00 55 0
TX 123456 01.10.2020 00:00:00 01.10.2020 00:00:00 155 100
TX 123456 01.10.2020 00:00:00 01.10.2020 00:00:00 175 20
BAL 123456 31.10.2020 00:00:00 01.11.2020 00:00:00 175 0
現在一切都准備好了,可以按帳戶和月份進行簡單的MIN
和MAX
聚合分組
with tx as (
select 'BAL' source, acct_id, monthend_date date_trnx, trunc(monthend_date+1,'MM') tx_month, balance, 0 trnxamt from AccountBalanceHistory
union all
select 'TX', acct_id, date_trnx,trunc(date_trnx,'MM') tx_month, trnxamt balance, trnxamt from Transaction
), tx2 as (
select
SOURCE, ACCT_ID, DATE_TRNX, TX_MONTH,
sum(BALANCE) over (partition by ACCT_ID,TX_MONTH order by date_trnx, decode (SOURCE,'BAL',1,'TX',2), trnxamt desc) as BALANCE,
TRNXAMT
from tx
where acct_id = 123456)
select acct_id, TX_MONTH, min(BALANCE), max(BALANCE)
from tx2
group by acct_id, TX_MONTH
order by 1,2;
ACCT_ID TX_MONTH MIN(BALANCE) MAX(BALANCE)
---------- ------------------- ------------ ------------
123456 01.09.2020 00:00:00 45 100
123456 01.10.2020 00:00:00 55 175
123456 01.11.2020 00:00:00 175 175
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.