如何使用SQL生成特定员工的往来结算余额变动报表?
如何使用SQL生成特定员工的往来结算余额变动报表?
我来帮你搞定这个问题!先看看你当前查询的问题出在哪,再给你一个能完美生成目标报表的方案。
你的查询问题分析
你原来的查询里有几个关键问题导致结果不符合预期:
- 多余的
GROUP BY id:id应该是每条交易记录的主键,分组后每行还是单独的交易,但这会让窗口函数里的SUM(amount)失去意义(单行的SUM就是自身值)。 - 窗口函数用法错误:
LAG(SUM(amount)) OVER (...)这种写法不对,LAG本身就是用来获取上一行的数据,不需要再嵌套求和窗口;而且ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING这个范围对LAG来说完全没必要,LAG默认就取前一行的数据。
正确的SQL写法
我们可以用CTE(公共表表达式)先计算出每个交易的累计余额,再通过LAG函数获取上一行的累计余额作为当前行的起始余额,同时格式化金额的正负展示,完全匹配你想要的报表格式:
WITH employee_transactions AS ( SELECT amount, -- 计算到当前交易为止的累计余额 SUM(amount) OVER (ORDER BY created_at) AS final_balance FROM settlement_settlement -- 过滤出你要查询的特定员工,替换成实际员工ID WHERE employee_id = '目标员工ID' -- 按交易时间排序,保证余额变动顺序正确 ORDER BY created_at ) SELECT -- 起始余额:上一行的最终余额,第一行默认是0 COALESCE(LAG(final_balance) OVER (ORDER BY created_at), 0) AS start_balance, -- 格式化变动金额,正数前面加+号 CONCAT(CASE WHEN amount >= 0 THEN '+' ELSE '' END, amount) AS change, final_balance AS final_balance FROM employee_transactions;
补充说明
- 如果需要在报表里展示其他字段(比如
reason、交易id),直接在CTE的SELECT里加上即可。 - 若存在同一时间的多条交易,可以再加一个排序字段(比如
id)来保证顺序稳定,修改为ORDER BY created_at, id。
这个查询运行后,就能得到和你示例完全一致的报表:逐行展示起始余额、变动金额、最终余额的变动记录。
备注:内容来源于stack exchange,提问作者Shukurullox Komiljonov
相关产品推荐
相关产品推荐

