sql >> Base de Datos >  >> RDS >> Mysql

Unión izquierda múltiple con suma

El problema podría ser el hecho debido a un resultado cartesiano de sus datos y sumas. Solo para aclarar, aquí hay una consulta simple... Sé que no lo tengo todo, ni unir columnas perfectamente, esto es solo para aclarar.

TAMBIÉN, SÉ que he abreviado las columnas y los alias para simplificar la lectura y la comprensión del concepto de lo que probablemente esté encontrando.

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

Al final, no hay problema... para un año determinado, obtendrá los totales de la segunda tabla. Hay muchos registros en la tabla 2. Ej:Datos

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

Probablemente estemos de acuerdo en eso en este punto... Ahora, agrega otra tabla que por año (o lo que sea), que también tiene múltiples registros por año...

Change_Orders
Yr     COAmt
2013   100
2013   120
2014   200
2014   220

Y agrega esto como una combinación izquierda secundaria a su consulta, algo así como

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

Sin embargo, dado que es un resultado cartesiano... varias filas por cada combinación están tomando los resultados VECES cada entrada que existe en la otra tabla... algo así como

Yr    AmtChange  COChangeAmt
2013  120         440
2014  180         840

Para solucionar esto, cada tabla individual de la que obtiene subtotales debe manejarse por sí sola y agruparse por su propio año para que el subconjunto devuelva solo una fila por contexto de datos. Algo como

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

Por lo tanto, cada una de las subconsultas devolverá solo 1 registro para el año respectivo que se agrega y, por lo tanto, evitará la duplicación en las cantidades de sum().