如何跟踪帐户的最小和最大余额
How to Track Min and Max Balance of an Account
我正在查看跟踪银行账户的最大和最小余额。有两个table:
AccountBalanceHistoryTable - 这记录了每个帐户在每个月底的余额
TransactionTable - 这记录了帐户上发生的所有交易
我创建了以下查询以将这两个 table 放在一起以获得 运行 余额,然后我将使用它来 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
Date_Trnx
Month_num
Year_num
Balance_Calc
123456
-55
29-Sep-20
9
2020
45
123456
10
30-Sep-20
9
2020
55
123456
100
1-Oct-20
10
2020
155
123456
20
1-Oct-20
10
2020
175
我遇到的问题是,上面说的是 10 月 1 日。在该帐户 10 月份发生任何交易之前,期初余额为 55 美元(9 月 30 日的期末余额)。这 55 美元实际上应该是我 10 月份的最低余额,但如果我采用上面的 table 和 select 2020 年 10 月的最低和最高余额,它将给我 155 美元的最低余额和最高余额175 美元,因为这些是上述子查询结果中显示的仅有的两条记录。
诀窍是 转移 月末 平衡从午夜到下个月的 1 号。
这里是余额table
的例子
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
和您的交易 table
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
查询 unions 两个来源并计算 trasnaction month,这是 1st 的余额下个月.
请注意,每一行都有它的来源 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
包含余额或交易金额,在我们添加之前它不是很有趣
对每个月使用分析窗口函数(从月初到当前行)
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
我正在查看跟踪银行账户的最大和最小余额。有两个table:
AccountBalanceHistoryTable - 这记录了每个帐户在每个月底的余额
TransactionTable - 这记录了帐户上发生的所有交易
我创建了以下查询以将这两个 table 放在一起以获得 运行 余额,然后我将使用它来 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 | Date_Trnx | Month_num | Year_num | Balance_Calc |
---|---|---|---|---|---|
123456 | -55 | 29-Sep-20 | 9 | 2020 | 45 |
123456 | 10 | 30-Sep-20 | 9 | 2020 | 55 |
123456 | 100 | 1-Oct-20 | 10 | 2020 | 155 |
123456 | 20 | 1-Oct-20 | 10 | 2020 | 175 |
我遇到的问题是,上面说的是 10 月 1 日。在该帐户 10 月份发生任何交易之前,期初余额为 55 美元(9 月 30 日的期末余额)。这 55 美元实际上应该是我 10 月份的最低余额,但如果我采用上面的 table 和 select 2020 年 10 月的最低和最高余额,它将给我 155 美元的最低余额和最高余额175 美元,因为这些是上述子查询结果中显示的仅有的两条记录。
诀窍是 转移 月末 平衡从午夜到下个月的 1 号。
这里是余额table
的例子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
和您的交易 table
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
查询 unions 两个来源并计算 trasnaction month,这是 1st 的余额下个月.
请注意,每一行都有它的来源 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
包含余额或交易金额,在我们添加之前它不是很有趣
对每个月使用分析窗口函数(从月初到当前行)
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