Pergunta

I am trying to get a running balance using SQL Server 2012

Here is what I got so far...

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

Results are

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

My goal is to have RunningBalance show each balance, even if its the same day, each row should have its own balance

As you can see, the 2nd row is not coming up correctly and I believe it is because I also have a 2nd account Id that is conflicting with it, but assumed the WHERE statement would remove it..

I can remove the ORDER BY, however I am wanting my list newest transaction first, as final query will have paging, and I have tried something like this.. but balance is off...

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

I'm not too sure what the problem is...

Foi útil?

Solução

Instead of ordering by TransactionId (a meaningless GUID value that has no bearing on when the row was inserted), you need to determine proper order in some other way. Since you have a CreatedOn column that stores the date/time the row was inserted, you should add that to your order by to generate the correct sequence.

Outras dicas

You're ordering your running balance differently than your results, so the rows don't coincide the way you think they should:

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

If you want to ORDER BY TransactionDate DESC then do so in your running balance too:

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

You can't have a meaningful running balance with disparate ORDER BY criteria.

I think what you need to use is ROWS UNBOUNDED PRECEDING.

SELECT TransactionDate
,Amount
,SUM(Amount) OVER (
    ORDER BY TransactionDate DESC ROWS UNBOUNDED PRECEDING
    ) AS [RunningBalance]
FROM @Transactions
WHERE AccountId = @AccountId
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top