Mysql
 sql >> Base de données >  >> RDS >> Mysql

Jointure gauche multiple avec somme

Le problème pourrait être le fait dû à un résultat cartésien de vos données et des sommations en cours. Juste pour clarifier, voici une simple requête... Je sais que je n'ai pas tout, ni joint les colonnes parfaites, c'est juste pour clarifier.

AUSSI, JE SAIS que j'ai abrégé les colonnes et les alias pour simplifier la lecture et la compréhension du concept de ce que vous rencontrez probablement.

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

A la fin, pas de problème... pour une année donnée, vous obtiendrez les totaux du deuxième tableau. Il y a beaucoup d'enregistrements dans le tableau 2. Ex :Données

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

Nous sommes probablement d'accord là-dessus à ce stade... Maintenant, ajoutez une autre table qui par an (ou autre), qui a aussi plusieurs enregistrements par an...

Change_Orders
Yr     COAmt
2013   100
2013   120
2014   200
2014   220

Et vous ajoutez ceci en tant que jointure gauche secondaire à votre requête, quelque chose comme

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

Cependant, comme il s'agit d'un résultat cartésien... plusieurs lignes par jointure prennent les résultats TIMES chaque entrée qui existe dans l'autre table... quelque chose comme

Yr    AmtChange  COChangeAmt
2013  120         440
2014  180         840

Pour résoudre ce problème, chaque table individuelle à partir de laquelle vous obtenez des sous-totaux doit être gérée seule et regroupée par sa propre année afin que le sous-ensemble ne renvoie qu'une seule ligne par contexte de données. Quelque chose comme

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

Ainsi, les sous-requêtes renverront chacune un seul enregistrement pour l'année respective en cours d'agrégation et éviteront ainsi la duplication des montants sum().