Reputation: 41
I have a table that looks like this
ID Type Amount Created
10 4 30,00 2019-11-29 11:34:54.417
1 1 10,50 2019-11-19 11:34:54.417
3 2 16,50 2019-11-17 11:34:54.417
2 4 11,50 2019-11-15 11:34:54.417
4 6 10,00 2019-11-11 11:34:54.417
5 3 8,60 2019-10-19 11:34:54.417
7 1 21,50 2019-05-19 11:34:54.417
8 4 9,00 2019-04-19 11:34:54.417
9 1 8,00 2019-02-19 11:34:54.417
6 1 1,50 2019-01-19 11:34:54.417
Imagine this table keeps an e-wallet and these are Transactions with ID , Type(withdrawals , reversals , deposits etc..) ,Amount and datetime Created. Lets say that all these 10 transactions refer to a specific Customer. Thus if i run
SELECT SUM(Amount) AS Balance
FROM transactions
WHERE Created <= '20191120'
this query will return the Balance of this customer until 2019/11/20.
What i want is to run a select query to this table and keep only the Transactions with Type=4. E.g.
SELECT ID
, Type
, Amount
, Created
FROM transactions
WHERE type=4
This query returns the following
ID Type Amount Created
2 4 11,50 2019-11-15 11:34:54.417
8 4 9,00 2019-04-19 11:34:54.417
10 4 30,00 2019-11-29 11:34:54.417
What i really want though is an extra column in this result set that shows the balance of the customer at the point of each transaction(with Type=4). For example when he did the Transaction with ID = 2 His balance before this(not counting the current(id=2) was (1,50+8,00+9,00+21,50+8,60+10,00) , when he did the Transaction with ID = 8 his balance was (1,50+8,00) and so on..
A desired Result set would be
ID Type Amount Created Balance
2 4 11,50 2019-11-15 11:34:54.417 58,60
8 4 9,00 2019-04-19 11:34:54.417 9,50
10 4 30,00 2019-11-29 11:34:54.417 97,1
I want to do this in one Select Query. I have some thoughts of doing it in two steps but that's not my intention, i Just need to run it once and have all five desired columns.
Upvotes: 0
Views: 2122
Reputation: 1269445
You want a cumulative sum and filtering:
SELECT t.*
FROM (SELECT t.*, SUM(Amount) OVER (ORDER BY Created) - Amount AS Balance
FROM transactions t
WHERE Created <= '20191120'
) t
WHERE type = 4;
Upvotes: 0
Reputation: 3823
Looking carefully at your desired output, assuming your DBMS supports window functions, you can do this using a pseudo-cumulative sum:
SELECT ID, Type, Amount, Created, Balance
FROM (
SELECT ID, Type, Amount, Created,
SUM(Amount) OVER(-- Sum "amount" of all rows before current row (exclude current row)
ORDER BY Created ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) AS Balance
FROM transactions
) src
WHERE type = 4
ORDER BY id
;
Also, shouldn't the balance for id=2
be 58,6
and the balance for id=10
be 97.1
?
Upvotes: 2