Reputation: 6799
First of all Sorry if my question title sounds stupid.... I have the following tables. The first table contains the name of my expenses type and the second table contains the information of amount and date of those expenses. If you notice the second table below there is a field called " e_id " which is the corresponding id value of my expenses from the first table.
First Table Name: expense_type
id expense_name
1 Insurance
2 Interest Payment
3 Rent
4 Electricity
... and goes on like this (unlimited perhaps :))
Second Table Name: expense_details
id e_id amount date
1 3 1000 2011-12-11
2 1 500 2011-12-19
3 4 10 2011-11-21
4 3 1000 2012-01-12
... and goes on like this )
Now my plan is to get all the values from these two tables and generate a result like following . But since the first table has unknown number of information (to me) I don't know how to write the query(both php and mysql) to generate such result.
Woud you please kindly help me on how to achieve this?
Thanks in Advance :)
P.S just for you information I am using Codeigniter.
**For the Month: January 2011**
Insurance : 1000
Rent : 3453
Electricity : 546
Interest Payment : 546
---------------------------------
**Total Expenses**: 938949 /// this value is just for an example
Upvotes: 3
Views: 2872
Reputation: 2050
SELECT ed.e_id, DATE_FORMAT(ed.date, '%M %Y') AS `month`, et.expense_name, SUM(ed.amount) AS `amount`
FROM expense_details ed
INNER JOIN expense_types et ON (et.id = ed.e_id)
WHERE (ed.date BETWEEN '2011-11-01' AND DATE_ADD('2011-11-01', INTERVAL 3 MONTH))
GROUP BY `month`, ed.e_id
WITH ROLLUP
You can set any date range of course, maybe even one month, or no date condition at all, to get full report.
It will sum expenses for each type with summary every month (you will have month
filled and ed.e_id
= NULL - that way you know it's summury for the month) and then for full time (both month
and ed.e_id
= NULL).
Output will be like this:
e_id month expense_name amount
1 December 2011 Insurance 500
3 December 2011 Rent 1000
NULL December 2011 Rent 1500
3 January 2012 Rent 1000
NULL January 2012 Rent 1000
4 November 2011 Electricity 10
NULL November 2011 Electricity 10
NULL NULL Electricity 2510
Of course you must ignore sticky expense_name
when you see e_id
= NULL
Some may suggest you just get results and then SUM them up with PHP, but it'll be a perfomance drain for large reports. Let SQL do what it does best (dig through data counting, summing, whatsoevering), and let PHP do what it does best (render HTML).
Of course SQl will reward you with even better performance if you have foreign keys set up correctly (that's why JOIN would work faster than just selecting from two tables and adding id=e_id
in WHERE clause) and have date
field indexed.
Upvotes: 0
Reputation: 56935
You can use the
SELECT expense_name, SUM(amount) as monthly_total
FROM expense_details, expense_type
WHERE expense_type.id=expense_details.e_id
AND `date` >= '2011-01-01'
AND `date` < '2011-02-01'
GROUP BY expense_details.e_id;
And then format as you wish. Note date
is in backticks since it's also a function in MySQL.
To change the month you just do `date
>= 'yyyy-mm-01' AND date
< 'yyyy-(mm+1)-01'(unless
mm` is December...).
You could alternatively do
WHERE MONTH(`date`)=1 AND YEAR(`date`)=2011,
or
WHERE `date`>='yyyy-mm-dd' AND `date`<DATE_ADD('yyyy-mm-dd',INTERVAL 1 MONTH)
for Jan 2011 (have a look here), but I reckon it's a bit slower if you don't have date indexed (of course which method you pick depends on the expected number of records you're sifting through, how the database is set up, etc etc -- but why not give a few versions a go and see what suits you?)
Upvotes: 4
Reputation: 8579
You can do this in a controller, or model:
$sql = "SELECT a.*, b.expense_name FROM expense_details AS a, expense_name AS b WHERE a.e_id = b.id ORDER BY a.id ASC";
$data = $this->db->query($sql)->result_array();
$totals = array();
echo '**For the Month: January 2011**';
echo "\n\n";
foreach ($data as $item){
$totals[$item['expense_name']] = isset($totals[$item['expense_name']]) ? $totals[$item['expense_name']] + $item['amount'] : $item['amount']:
}
foreach ($totals as $name => $val){
echo $name.': '.$val;
echo "\n\n";
}
Not the most elegant, or stable method but I hope this helps give you the idea of what you need to do. You'll also probably want to break totals up by month I suppose.
Upvotes: 0