【问题标题】:How to perform running sum (balance) in SQL如何在 SQL 中执行运行总和(余额)
【发布时间】:2012-07-16 13:27:50
【问题描述】:

我有 2 个 SQL 表

unit_transaction unit_detail_transactions

(此处的表架构:http://sqlfiddle.com/#!3/e3204/2

我需要执行 SQL 查询以生成包含余额的表。现在我有这个 SQL 查询,但它不能正常工作,因为当我有 2 笔相同日期的交易时,余额计算不正确。

SELECT 
ft.transactionid,
ft.date,
ft.reference,
ft.transactiontype,
CASE ftd.isdebit WHEN 1 THEN MAX(ftd.debitaccountid) ELSE MAX(ftd.creditaccountid) END as financialaccountname,
CAST(COUNT(0) as tinyint) as totaldetailrecords,
ftd.isdebit,
SUM(ftd.amount) as amount,
balance.amount as balance
FROM unit_transaction_details ftd
JOIN unit_transactions ft ON ft.transactionid = ftd.transactionid
JOIN
(
    SELECT DISTINCT
    a.transactionid,
    SUM(CASE b.isdebit WHEN 1 THEN b.amount ELSE -ABS(b.amount) END) as amount
    --SUM(b.debit-b.credit) as amount
    FROM unit_transaction_details a
    JOIN unit_transactions ft ON ft.transactionid = a.transactionid
    CROSS JOIN unit_transaction_details b
    JOIN unit_transactions ft2 ON ft2.transactionid = b.transactionid
    WHERE (ft2.date <= ft.date)
    AND ft.unitid = 1
    AND ft2.unitid = 1
    AND a.masterentity = 'CONDO-A'
    GROUP BY a.transactionid,a.amount

) balance ON balance.transactionid = ft.transactionid

WHERE 
ft.unitid = 1
AND ftd.isactive = 1
GROUP BY 
ft.transactionid,
ft.date,
ft.reference,
ft.transactiontype,
ftd.isdebit,
balance.amount
ORDER BY ft.date DESC

查询的结果是这样的:

关于如何执行正确的 SQL 以显示后代模式下按交易日期排序的正确余额的任何线索?

非常感谢。

编辑:考虑 2 个可能的解决方案

当您在 2 个交易中具有相同的日期时会产生问题,所以这是我要做的:

  1. 将日期和时间保存到“日期”列中。这样就不会有 2 个确切的日期。

  1. 创建“优先级”列并为每条记录设置优先级。因此,如果我发现日期已经存在并且它的优先级 = 1,那么当前的优先级将为 2。

你怎么看?

【问题讨论】:

  • 我鼓励您对此进行一些研究。这是一个常见的问题,很多关于堆栈溢出的答案已经存在。
  • 您是否有理由对子查询中的事务详细信息表执行 CROSS JOIN(笛卡尔积)?

标签: sql accounting


【解决方案1】:

有两种方法可以计算运行总和。我将在一个更简单的表格上展示语法,给你一个想法。

某些数据库(例如 Oracle、PostgreSQL、SQL Server 2012、Teradata、DB2)直接支持累积和。为此,您使用以下功能:

select sum(<val>) over (partition by <column> order by <ordering column>)
from t

这是一个 windows 函数,它将计算由 标识的每组记录的运行总和。和的顺序是。

唉,许多数据库不支持此功能,因此您需要在数据库中的单个 SELECT 查询中执行自连接:

select t.column, sum(tprev.<val>) as cumsum
from t left join
     t tprev
     where t.<column> = tprev.<column> and
           t.<ordering column> >= tprev.<ordering column>
group by t.column

还可以创建另一个表并使用游标来分配累积和,或者在应用程序级别进行求和。

【讨论】:

    猜你喜欢
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2014-06-02
    相关资源
    最近更新 更多