多个左连接和

时间:2015-02-04 19:15:13

标签: php mysql sql sum left-join

我尝试在sql查询中使用Left Join从3个表中求和显示在表(带有数据表插件)信息中。 我成功编辑了服务器端查询,并使用以下查询在两个表(t1 = ... budget& t2 = .. budget_changes)之间首次连接显示正确的数据:

$year=date('Y');

$sQuery = "SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns)).", 

IFNULL(SUM(t2.change_amount),0) AS operation_changes,
(t1.operation_BP+IFNULL(SUM(t2.change_amount),0)) AS operation_total 
FROM budget AS t1 

LEFT JOIN wp_dri_budget_changes AS t2 ON t2.change_year_operation=t1.operation_year_number 

WHERE t1.operation_year=".$year." AND t1.operation_active=1 $sWhere

GROUP BY operation_year_number, change_year_operation $sOrder $sLimit";

但是当我试图用左联合查询连接3个表时,总和结果是错误的。

$year=date('Y');

$sQuery = "SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns)).",

IFNULL(SUM(t2.change_amount),0) AS operation_changes,

(t1.operation_BP+IFNULL(SUM(t2.change_amount),0)) AS operation_total,

IFNULL(SUM(t3.expense_enga_amount),0) AS operation_consommation

FROM budget AS t1

LEFT JOIN wp_dri_budget_changes AS t2 ON t2.change_year_operation=t1.operation_year_number

LEFT JOIN wp_dri_budget_expenses AS t3 ON t3.expense_year_operation=t1.operation_year_number 

WHERE t1.operation_year=".$year." AND t1.operation_active=1 $sWhere GROUP BY operation_year_number, change_year_operation, expense_year_operation $sOrder $sLimit";

此查询有什么问题?非常感谢MT

2 个答案:

答案 0 :(得分:0)

问题可能是由于您的数据和摘要的笛卡尔结果而导致的事实。只是为了澄清,这是一个简单的查询...我知道我没有这一切,也没有完美的列,这只是为了澄清。

另外,我知道我缩写了列和别名,以简化阅读和理解你可能遇到的概念。

Select
      t1.yr,
      sum( t2.Amt ) as AmtChange
   FROM 
      budget AS t1
         LEFT JOIN Budget_Changes AS t2
            on t1.yr = t2.Yr

最后,没问题......对于某一年,你将获得第二张表中的总数。表2中有许多记录。例如:数据

Budget
Yr
2013
2014

Budget_Changes
Yr    Amt
2013  10
2013  20
2013  30
2014  40
2014  50

Your results would be
Yr    AmtChange
2013  60
2014  90

我们现在可能就此达成一致......现在,扔进另一张每年(或其他)的表格,每年也有多个记录......

Change_Orders
Yr     COAmt
2013   100
2013   120
2014   200
2014   220

然后将其作为辅助左连接添加到您的查询中,例如

Select
      t1.yr,
      sum( t2.Amt ) as AmtChange,
      sum( t3.COAmt ) as COAmtChange
   FROM 
      budget AS t1
         LEFT JOIN Budget_Changes AS t2
            on t1.yr = t2.Yr
         LEFT JOIN Change_Orders AS t3
            on t1.yr = t3.Yr


Your might expect the results to be
Yr    AmtChange  COChangeAmt
2013  60         220
2014  90         420

但是,因为它是笛卡尔结果...每个连接的多个行将结果TIMES存在于另一个表中的每个条目...类似

Yr    AmtChange  COChangeAmt
2013  120         440
2014  180         840

要解决此问题,您要获取小计的每个单独的表应该单独处理,并按其自己的年份进行分组,因此该子集每个数据上下文只返回一行。像

这样的东西
Select
      t1.yr,
      t2.AmtChange,
      t3.COAmtChange
   FROM 
      budget AS t1
         LEFT JOIN ( select BC.Yr, sum( BC.Amt ) as AmtChange
                        from Budget_Changes BC
                        group by BC.Yr ) t2
            on t1.yr = t2.Yr
         LEFT JOIN ( select CO.Yr, sum( CO.COAmt ) as COAmtChange
                        from Change_Orders CO
                        group by CO.Yr ) AS t3
            on t1.yr = t3.Yr

因此,子查询将分别返回聚合的相应年份的1条记录,从而防止sum()数量的副本。

答案 1 :(得分:0)

这是决赛,似乎有效。

$year=date('Y');
$sQuery = "SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns)).", 
t2.total_changes,
t1.operation_BP+IFNULL(total_changes,0) AS operation_total, 
t3.total_conso
FROM $sTable AS t1
LEFT JOIN (SELECT tt2.change_year_operation, IFNULL(SUM(tt2.change_amount),0) AS total_changes FROM wp_dri_budget_changes tt2 GROUP BY tt2.change_year_operation) t2 ON t1.operation_year_number = t2.change_year_operation
LEFT JOIN (SELECT tt3.expense_year_operation, IFNULL(SUM(tt3.expense_enga_amount),0) AS total_conso FROM wp_dri_budget_expenses tt3 GROUP BY tt3.expense_year_operation) AS t3 ON t1.operation_year_number = t3.expense_year_operation
WHERE t1.operation_year=".$year." AND t1.operation_active=1 $sWhere $sOrder $sLimit";

OPERATION_NUMBER NAME BP CHANGES TOTAL TOTAL_CONSO


15P731OV001 project1 28000(null)28000(null)

13P0012OV001 project2 612500 -60000 552500 21000

**但现在IFNULL(x,0)似乎不再工作了,当和结果为NULL时显示为null(数据表中的NaN.N)**