SQL窗口函数和运行总计
Posted
技术标签:
【中文标题】SQL窗口函数和运行总计【英文标题】:SQL window function and running total 【发布时间】:2021-07-16 13:35:17 【问题描述】:我正在学习 SQL,想更好地理解窗口函数。
假设我有一组银行帐户的数据,其中包含:
-
最新余额(仅显示最新余额,不显示历史余额)
交易日期
入金金额
提现金额
从这些数据中,我想得到一个列,显示everey 交易中的运行总计(“余额”),如下所示:
account | latest_balance | date | deposit | withdrawal | balance |
---|---|---|---|---|---|
XYZ | 1 000 | 2021-07-16 | 100 | 1 000 | |
XYZ | 1 000 | 2021-07-15 | 200 | 900 |
由于数据不包含该账户的全部交易历史,并且可用日期是最近 1 年,因此获取“余额”的一种方法是根据最新余额进行计算。我已经尝试为此使用窗口功能。但是我无法让它按照我想要的方式工作。
例如,如果我将 select 语句的这一部分写成如下:
SELECT
latest_balance
- (ISNULL (SUM(deposit) OVER(PARTITION BY account ORDER BY date DESC ROWS UNBOUNDED PRECEDING),0)
+ ISNULL (SUM(withdrawal)) OVER(PARTITION BY account ORDER BY date DESC ROWS UNBOUNDED PRECEDING),0))
这将返回如下内容:
account | latest_balance | date | deposit | withdrawal | balance |
---|---|---|---|---|---|
XYZ | 1 000 | 2021-07-16 | 100 | 900 | |
XYZ | 1 000 | 2021-07-15 | 200 | 700 |
这不是我希望看到的,因为第一行的余额应该是 1 000 而不是 900。我为此尝试了 ROWS、BETWEEN、UNBOUNDED、PRECEDING 和 FOLLOWING 的不同组合,但我仍然想不通了解如何使它工作。
有人可以分享您的知识并启发我吗?非常感谢! =)
【问题讨论】:
对于 mysql,请参见:this,对于 MSSQL,请参见:this。两者都解释了您应该(或希望?)了解的基本知识。 【参考方案1】:您似乎希望 latest_balance
将 deposit
和 withdrawal
的累积总和删除直到上一行。
那就是:
select t.*,
(latest_balance -
coalesce(sum(deposit) over (partition by account order by date rows between unbounded preceding and 1 preceding), 0) +
coalesce(sum(withdrawal) over (partition by account order by date rows between unbounded preceding and 1 preceding), 0)
) as balance
from t;
【讨论】:
以上是关于SQL窗口函数和运行总计的主要内容,如果未能解决你的问题,请参考以下文章