Account balance: how to calculate it properly on SQL

Felipe picture Felipe · Oct 21, 2014 · Viewed 10k times · Source

I'm developing an application where I'll have to store some bank account informations, including daily account balances.

So, for instance:

17/10/2014 - (+) - Starting/Initial balance - 5,000.00
17/10/2014 - (=) - Balance - 5,000.00
-
18/10/2014 - (-) - Payment - (1,000.00)
18/10/2014 - (=) - Balance - 4,000.00
-
19/10/2014 - (=) - Balance - 4,000.00
-
20/10/2014 - (-) - Payment - (1,000.00)
20/10/2014 - (=) - Balance - 3,000.00

I think I could create a specific "account_balance" table where I could store every account balances for each day.

If I'm wrong, could you help me on finding the best way to do that? However, if I'm right, how can I make the database calculate daily balances and, specially, how can I make the database update balances when an user starts editing older values?

And by "older values", I mean:

1 - This is what "Account A" statement looks like:

18/10/2014 - (+) - Starting/Initial balance - 5,000.00
18/10/2014 - (=) - Balance - 5,000.00
-
19/10/2014 - (=) - Balance - 5,000.00
-
20/10/2014 - (=) - Balance - 5,000.00

2 - But the user forgot to register an income, so he does it by adding a new income (so now balances must be updated):

18/10/2014 - (+) - Starting/Initial balance - 5,000.00
18/10/2014 - (+) - Sales commission - 2,500.00 <- USER ADDED THIS.
18/10/2014 - (=) - Balance - 7,500.00 <- THIS BALANCE HAS BEEN UPDATED.
-
19/10/2014 - (=) - Balance - 7,500.00 <- THIS BALANCE HAS BEEN UPDATED.
-
20/10/2014 - (=) - Balance - 7,500.00 <- THIS BALANCE HAS BEEN UPDATED.

Answer

Eric B. picture Eric B. · Oct 21, 2014

Instead of storing balances, have a table which stores the transactions only for each user.

For example:

Date            Transactions        Comment
17/10/2014      +5,000.00           Starting/Initial balance - 
18/10/2014      -1,000.00           Payment
20/10/2014      -1,000.00           Payment

Then you can create a balance view (something like):

create view balance as
  select userId, sum(transactions) as balance from TransactionTable group by userId

If you want to be more precise and include start and stop dates (ie: to be able to get a balance at any point in time) you can create a parametrized view (haven't tried it using dates, but I presume it would work as well).