I\'m trying to display in a table (with data tables plugin) informations with sum from 3 tables using Left Join in sql query. I succeeded to edit server-side query and disp
The problem might be the fact due to a Cartesian result of your data and summations going on. Just to clarify, here is a simple query... I know I don't have it all, nor join columns perfect, this is just for clarification.
ALSO, I KNOW I have abbreviated the columns and aliases for simplified reading and understanding of the concept of what you are probably encountering.
Select
t1.yr,
sum( t2.Amt ) as AmtChange
FROM
budget AS t1
LEFT JOIN Budget_Changes AS t2
on t1.yr = t2.Yr
At the end, no problem... for a given year, you will get the totals from the second table. There are many records in table 2. Ex: Data
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
We probably agree on that at this point... Now, throw in another table that per year (or whatever), that too has multiple records per year...
Change_Orders
Yr COAmt
2013 100
2013 120
2014 200
2014 220
And you add this in as a secondary left-join to your query, something like
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
However, since it is a Cartesian result... multiple rows per each join is taking the results TIMES each entry that exists in the other table... something like
Yr AmtChange COChangeAmt
2013 120 440
2014 180 840
To fix this, each individual table you are getting subtotals from should be handled on its own, and grouped by its own year so the subset returns only one row per context of data. Something like
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
So, the sub-queries will each return only 1 record for the respective year being aggregated and thus prevent the duplicate in sum() amounts.
That is the final and seems to work.
$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
**But now IFNULL(x,0) seems not working anymore and null (NaN.N in datatables) are display when sum results are NULL **