【发布时间】:2021-02-23 15:48:54
【问题描述】:
我正在研究跟踪银行账户的最高和最低余额。有两个表:
AccountBalanceHistoryTable - 记录每个月末每个账户的余额
TransactionTable - 这记录了一个帐户上发生的所有交易
我创建了以下查询以将这两个表放在一起以获得运行余额,然后我将使用该查询从中选择最大和最小余额:
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 月的最低余额,但如果我使用上表并选择 2020 年 10 月的最低和最高余额,它将给我 155 美元的最低余额和 175 美元的最高余额,因为这是仅有的两个上述子查询结果中显示的记录。
【问题讨论】:
-
开始的一般问题:您是否真的需要查看每月期末余额表?无论如何都不能从事务表中计算出来吗?如果是这样,那么仅基于事务表进行所有计算可能会更容易(也更有效)。我可以告诉你如何(很多人可以告诉你如何),但首先请确认这实际上是正确的。
-
@MarmiteBomber - 这就是我问的原因。至少在“先进”国家,在“信誉良好”的银行,通常会保存从账户开始的完整交易历史,即使在数据仓库中的计算通常基于上个月的期末余额。如果 OP 无论如何都需要查看单个事务(因为他必须执行他的任务),这意味着他必须查看单个事务。或者,我们需要每个帐户一个期初余额,而不是每个月的期初余额。
-
另一个需要澄清的问题。您的数据仅显示交易日期(无时间部分)。这是正确的,还是交易记录在一天中的时间?无论哪种方式 - 两个交易可以同时发生吗?如果是这样,你如何处理计算余额?除非您在计算新余额之前汇总它们,否则您将有歧义。例如,在同一笔交易中存款 30 和取款 20(相同的时间戳) - 是否显示为单笔存款 10?如果不是,您是先加 30 还是先减 20 来计算滚动余额?
-
@Marmite Bomber - 这非常有效 - 非常感谢。只是为了我自己的学习,使用“With”语句有什么好处?据我所知,它只是让查询更简单一些?我想同样的事情可以用单独的选择语句来完成,然后两者之间的联合(即一个用于余额历史记录和一个用于交易)?
-
@Marmite Bomber - 另外 - 我想我理解解码语句的用途 - 基本上是为 AccountBalanceHistoryTable 中的记录分配“1”,为 TransactionTable 中的记录分配“2”如果在余额历史记录的同一天有交易,订购目的是什么?我应该提到交易日期通常有一个与之相关的时间戳,但我很高兴这无论如何都能正常工作。再次感谢!
标签: sql oracle oracle-sqldeveloper