如何连接两个表,然后显示从另一个表收集的表的每个数据的总和值

时间:2011-12-27 13:25:04

标签: php mysql codeigniter codeigniter-2

首先对不起,如果我的问题标题听起来很愚蠢......我有以下表格。第一个表包含我的费用类型的名称,第二个表包含这些费用的金额和日期的信息。如果您注意到下面的第二个表,则会出现一个名为“e_id”的字段,该字段是第一个表中我的费用的相应ID值。

第一个表名:expense_type

  id     expense_name 

  1        Insurance
  2        Interest Payment
  3        Rent
  4        Electricity

 ... and goes on like this (unlimited perhaps :))

第二个表名称: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 )

现在我的计划是从这两个表中获取所有值并生成如下结果。但由于第一个表有未知数量的信息(对我而言),我不知道如何编写查询(包括php和mysql)来生成这样的结果。

请你帮忙告诉我如何实现这个目标?

提前致谢:)

P.S仅为您提供信息我正在使用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

3 个答案:

答案 0 :(得分:4)

您可以使用

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;

然后按照您的意愿进行格式化。注意date是反引号,因为它也是MySQL中的一个函数。

要更改月份,您只需`date&gt; ='yyyy-mm-01'和date&lt; 'yyyy-(mm + 1)-01'(unless mm`是十二月......)。

你可以选择

WHERE MONTH(`date`)=1 AND YEAR(`date`)=2011, 

WHERE `date`>='yyyy-mm-dd' AND `date`<DATE_ADD('yyyy-mm-dd',INTERVAL 1 MONTH)

2011年1月(看看here),但我认为如果你没有索引日期会有点慢(当然你选择哪种方法取决于你正在筛选的预期记录数量)通过,如何设置数据库等等 - 但为什么不给一些版本去看看适合你的东西?)

答案 1 :(得分:0)

您可以在控制器或型号中执行此操作:

$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";
}

不是最优雅或最稳定的方法,但我希望这有助于您了解您需要做什么。你可能也想在一个月内打破总数。我猜想。

答案 2 :(得分:0)

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

您可以设置任何日期范围,当然,甚至一个月,或根本没有日期条件,以获得完整的报告。 它将每个类型的费用与每月的摘要相加(您将填充month并且ed.e_id = NULL - 这样您知道它是本月的总和)然后是全职({{1} }和month = NULL)。

输出将如下:

ed.e_id

当您看到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 = NULL

时,您必须忽略粘性expense_name

有些人可能会建议你只是得到结果,然后用PHP来理解它们,但这对于大型报告来说是个性能消耗。让SQL做它最擅长的事情(挖掘数据计数,求和,无论如何),让PHP做它最擅长的事情(渲染HTML)。

当然,如果正确设置了外键,SQl将奖励你更好的性能(这就是为什么JOIN比仅从两个表中选择并在WHERE子句中添加e_id更快的工作)并且{{1字段索引。