Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Multiple Left Join mit Summe

Das Problem könnte an einem kartesischen Ergebnis Ihrer Daten und Summationen liegen. Nur zur Verdeutlichung, hier ist eine einfache Abfrage... Ich weiß, dass ich nicht alles habe, noch Spalten perfekt verbinden, dies dient nur zur Verdeutlichung.

Außerdem weiß ich, dass ich die Spalten und Aliase abgekürzt habe, um das Lesen und Verstehen des Konzepts dessen, was Sie wahrscheinlich antreffen, zu vereinfachen.

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

Am Ende kein Problem ... für ein bestimmtes Jahr erhalten Sie die Gesamtsummen aus der zweiten Tabelle. Es gibt viele Datensätze in Tabelle 2. Beispiel:Daten

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

Darin sind wir uns an dieser Stelle wahrscheinlich einig... Nun, wirf eine weitere Tabelle ein, die pro Jahr (oder was auch immer) ebenfalls mehrere Datensätze pro Jahr hat...

Change_Orders
Yr     COAmt
2013   100
2013   120
2014   200
2014   220

Und Sie fügen dies als sekundären Left-Join zu Ihrer Abfrage hinzu, so etwas wie

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

Da es sich jedoch um ein kartesisches Ergebnis handelt ... nehmen mehrere Zeilen pro Join die Ergebnisse MAL für jeden Eintrag, der in der anderen Tabelle vorhanden ist ... so etwas wie

Yr    AmtChange  COChangeAmt
2013  120         440
2014  180         840

Um dies zu beheben, sollte jede einzelne Tabelle, aus der Sie Zwischensummen erhalten, separat behandelt und nach ihrem eigenen Jahr gruppiert werden, sodass die Teilmenge nur eine Zeile pro Datenkontext zurückgibt. So etwas wie

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

Die Unterabfragen geben also jeweils nur 1 Datensatz für das jeweilige aggregierte Jahr zurück und verhindern so die Duplizierung in sum() Beträgen.