【问题标题】:Running Balance in SQL Server 2012SQL Server 2012 中的运行平衡
【发布时间】:2013-08-15 19:38:56
【问题描述】:

我正在尝试使用 SQL Server 2012 获得运行平衡

这是我目前得到的...

DECLARE @Transactions TABLE
(
    Amount decimal (18,2),
    TransactionId uniqueidentifier,
    AccountId uniqueidentifier,
    TransactionDate date
)

DECLARE @AccountId uniqueidentifier = NEWID()

INSERT INTO @Transactions (Amount, TransactionId, AccountId, TransactionDate)
SELECT 3224.99, NEWID(), @AccountId, '2013-06-02'

INSERT INTO @Transactions (Amount, TransactionId, AccountId, TransactionDate)
SELECT 18.99, NEWID(), NEWID(), '2013-06-14'

INSERT INTO @Transactions (Amount, TransactionId, AccountId, TransactionDate)
SELECT -8.99, NEWID(), @AccountId, '2013-06-14' 

INSERT INTO @Transactions (Amount, TransactionId, AccountId, TransactionDate)
SELECT -6.99, NEWID(), @AccountId, '2013-06-14'

INSERT INTO @Transactions (Amount, TransactionId, AccountId, TransactionDate)
SELECT -22.14, NEWID(), @AccountId, '2014-11-09'

INSERT INTO @Transactions (Amount, TransactionId, AccountId, TransactionDate)
SELECT -84.99, NEWID(), @AccountId, '2013-06-09'


SELECT  SUM(Amount) OVER (ORDER BY TransactionDate, TransactionId) as [RunningBalance],
        Amount
FROM @Transactions 
WHERE AccountId = @AccountId
ORDER BY TransactionDate DESC

结果是

RunningBalance                          Amount
--------------------------------------- ---------------------------------------
3101.88                                 -22.14
3133.01                                 -6.99
3124.02                                 -8.99
3140.00                                 -84.99
3224.99                                 3224.99

我的目标是让 RunningBalance 显示每个余额,即使是同一天,每一行也应该有自己的余额

如您所见,第二行没有正确显示,我相信这是因为我还有一个与之冲突的第二个帐户 ID,但假设 WHERE 语句会删除它..

我可以删除 ORDER BY,但是我希望我的列表是最新交易,因为最终查询将有分页,我已经尝试过类似的操作..但是余额已关闭...

SELECT * FROM (
SELECT  SUM(Amount) OVER (PARTITION BY AccountId ORDER BY TransactionDate, TransactionId) as [RunningBalance],
        Amount, TransactionDate
FROM @Transactions 
WHERE AccountId = @AccountId
) AS Results
ORDER BY TransactionDate DESC




RunningBalance                          Amount                                  TransactionDate
--------------------------------------- --------------------------------------- ---------------
3101.88                                 -22.14                                  2014-11-09
3131.01                                 -8.99                                   2013-06-14
3124.02                                 -6.99                                   2013-06-14
3140.00                                 -84.99                                  2013-06-09
3224.99                                 3224.99                                 2013-06-02

我不太确定问题是什么......

【问题讨论】:

  • 如果两行具有相同的日期,我不知道您如何期望知道哪一行是第一个。此外,如果行将 NEWID() 分配给 TransactionID,我不明白为什么您需要在聚合中按此排序 - 这可能有什么用途?
  • 我在想添加 Id 会允许它计算它,即使值是相同的日期.. 它确实但不正确,如果我删除 Id 相同日期的 2 笔交易将具有完全相同的金额
  • 您需要其他东西(标识列、序列号、时间列,或使用日期时间而不是日期等)来区分同一天的两个值以及顺序他们发生了。
  • 哦,对了,这会有所帮助.. 我确实有一个 CreatedOn 列,而不是我使用的 Id,它工作得很好.. 数量匹配正确..

标签: sql sql-server-2012 cumulative-sum


【解决方案1】:

您需要以其他方式确定正确的顺序,而不是按 TransactionId(一个无意义的 GUID 值,与插入行的时间无关)进行排序。由于您有一个 CreatedOn 列来存储插入该行的日期/时间,因此您应该将其添加到您的 order by 以生成正确的序列。

【讨论】:

    【解决方案2】:

    您对运行余额的排序与结果不同,因此行与您认为应该的方式不一致:

    SELECT  SUM(Amount) OVER (ORDER BY TransactionDate, TransactionId) as [RunningBalance],
            Amount
    FROM @Transactions 
    WHERE AccountId = @AccountId
    ORDER BY TransactionDate, TransactionId
    

    如果你想ORDER BY TransactionDate DESC,那么也可以在你的余额中这样做:

    SELECT  SUM(Amount) OVER (ORDER BY TransactionDate DESC, TransactionId) as [RunningBalance],
            Amount
    FROM @Transactions 
    WHERE AccountId = @AccountId
    

    在不同的ORDER BY 条件下,您无法获得有意义的运行平衡。

    【讨论】:

    • 我这样做是因为我将要对列表进行分页,并且我希望首先获得较新的交易
    • 我明白你在说什么,即使我在 WHERE 结果匹配之后删除了 ORDER BY .. 但问题是当我尝试先按新排序时,数字不匹配正确,我会修改问题以显示它
    【解决方案3】:

    我认为您需要使用的是 ROWS UNBOUNDED PRECEDING。

    SELECT TransactionDate
    ,Amount
    ,SUM(Amount) OVER (
        ORDER BY TransactionDate DESC ROWS UNBOUNDED PRECEDING
        ) AS [RunningBalance]
    FROM @Transactions
    WHERE AccountId = @AccountId
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多