Assuming you make transactions during the day, I adopted the following scheme:
CREATE TABLE transaction ( tran_date date, num int, withdraw numeric, deposit numeric ); INSERT INTO transaction VALUES ('2010-11-23', 1, 0.00, 50.00), ('2010-12-10', 1, 0.00, 50.00), ('2010-12-10', 2, 0.00, 200.00), ('2010-12-12', 1, 100.00, 0.00), ('2010-12-20', 1, 0.00, 50.00), ('2010-12-20', 2, 70.00, 0.00), ('2010-12-20', 3, 0.00, 50.00), ('2010-12-20', 4, 0.00, 50.00), ('2010-12-24', 1, 150.00, 0.00);
Then the following request appears, which will give you an answer:
WITH dates (tran_date) AS (SELECT date '2010-12-01' + generate_series(0, 30)), transactions AS (SELECT tran_date, num, coalesce(withdraw, 0) AS withdraw, coalesce(deposit, 0) AS deposit FROM dates FULL OUTER JOIN transaction USING (tran_date)), running_totals AS (SELECT tran_date, sum(deposit - withdraw) OVER (ORDER BY tran_date, num ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS lagging_total, sum(deposit - withdraw) OVER (ORDER BY tran_date, num ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS current_total FROM transactions) SELECT tran_date, min(least(lagging_total, current_total)) FROM running_totals GROUP BY tran_date HAVING tran_date IN (SELECT tran_date FROM dates) ORDER BY tran_date;
Please note that for this you need PostgreSQL 9.0, because the 1 PRECEDING not supported in earlier versions. If you cannot update, you will probably need some kind of procedural solution, like the other answers.
In any case, I recommend writing unit tests for this .; -)