简体   繁体   中英

How to join two tables and then display the sum value of each data of a table gathering from the other table

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 :)

PS 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

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?)

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM