Question

First, my table:

mysql> desc invoice;
+-------------+-----------------------+------+-----+---------+----------------+
| Field       | Type                  | Null | Key | Default | Extra          |
+-------------+-----------------------+------+-----+---------+----------------+
| id          | int(11)               | NO   | PRI | NULL    | auto_increment |
| date        | timestamp             | YES  |     | NULL    |                |
| sent        | timestamp             | YES  |     | NULL    |                |
| due_date    | timestamp             | YES  |     | NULL    |                |
| amount      | float                 | YES  |     | NULL    |                |
| amount_due  | float                 | YES  |     | NULL    |                |
| status      | enum('unpaid','paid') | YES  |     | NULL    |                |
| customer_id | int(11)               | NO   | MUL | NULL    |                |
+-------------+-----------------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

Can anyone help me come up with a query that will return, for each row:

The day (so group by due_date) The starting balance of the day (This would be the end balance of the previous day) Inflow (the total of the POSITIVE transactions for the day) Outflow (the total of the NEGATIVE transactions for the day) Ending balance (The ending balance of the day after all the inflow and outflow transactions have been applied)

Basically every day I want to know how much money was deposited, how much money was withdrawn, the balance of the day started at, and the ending balance.

I should also specify that for the day, I want to group the rows by "due_date" and use the "amount" column as the basis for all transactions (ignoring the amount_due).

Any ideas?

I could start going down the path of making another table that holds just this info but thought maybe someone can come up with a nifty query that can do this off the actual data.

Was it helpful?

Solution

Here's my take on it. Basically you join back on the invoice table by

todaydata.due_date=DATE_ADD(yesterdaydata.due_date,DAY,-1)

so you have access to yesterday's amount_due field (i did a left join so if you ask for the first day in your table, you'll still get a record back)

The rest is pretty straightforward. I wasn't sure if today's ending balance was the sum of yesterday + inflow + outflow or if it was just the sum of todaydata.amount_due, so I included both.

SELECT 
todaydata.due_date,
SUM(case when yesterdaydata.amount_due is null then 0 else yesterdaydata.amount_due end )) AS StartingBalance,
SUM(CASE when todaydata.amount > 0 THEN todaydata.amount ELSE 0 END)  AS INFLOW,
SUM(CASE when todaydata.amount < 0 THEN todaydata.amount ELSE 0 END)  AS OUTFLOW,
SUM(yesterday.amount_due) AS StartingBalance +
            SUM(CASE where todaydata.amount > 0 THEN todaydata.amount ELSE 0 END)  + 
            SUM(CASE where todaydata.amount < 0 THEN todaydata.amount ELSE 0 END)  AS CalculatedEndingBalance,
SUM(todaydata.amount_due) AS OtherEndingBalance
FROM invoice [todaydata]
LEFT JOIN invoice [yesterdaydata] ON todaydata.due_date=DATE_ADD(yesterdaydata.due_date,DAY,-1)
GROUP BY todaydata.due_date

I didn't have the ability to test this against a mysql database so let me know of any syntax errors and i'll correct.

OTHER TIPS

You would need to split your transactions from your invoice tables like so:

TABLE invoice (
   id int autoincrement,
   due_date date,
   customer_id int,
   sent_date date
);

TABLE transaction (
   id int autoincrement primary key
   transaction_date date,
   amount double,
   transaction_type enum ("charge", "payment"),
   customer_id int
);

After you are done creating the transaction table you can easily get what you need by:

SELECT SUM(amount), transaction_type, transaction_date, customer_id FROM transaction GROUP BY customer_id, transaction_date, transaction_type
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top