Multiple Left Join with sum

后端 未结 2 726
深忆病人
深忆病人 2021-01-16 07:35

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

相关标签:
2条回答
  • 2021-01-16 07:59

    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.

    0 讨论(0)
  • 2021-01-16 08:12

    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 **

    0 讨论(0)
提交回复
热议问题