首先对不起,如果我的问题标题听起来很愚蠢......我有以下表格。第一个表包含我的费用类型的名称,第二个表包含这些费用的金额和日期的信息。如果您注意到下面的第二个表,则会出现一个名为“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
答案 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字段索引。