Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wielokrotne połączenie lewe z sumą

Problem może wynikać z kartezjańskiego wyniku Twoich danych i trwających podsumowań. Dla wyjaśnienia, oto proste zapytanie... Wiem, że nie mam tego wszystkiego, ani nie łączę idealnie kolumn, to tylko dla wyjaśnienia.

RÓWNIEŻ WIEM, że skróciłem kolumny i aliasy, aby ułatwić czytanie i zrozumienie koncepcji tego, z czym prawdopodobnie się spotykasz.

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

Na koniec nie ma problemu... za dany rok otrzymasz sumy z drugiej tabeli. W tabeli 2 jest wiele rekordów. Np.:Dane

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

Prawdopodobnie w tym momencie się z tym zgadzamy... Teraz wrzuć inną tabelę, która rocznie (lub cokolwiek), która również ma wiele rekordów rocznie...

Change_Orders
Yr     COAmt
2013   100
2013   120
2014   200
2014   220

I dodajesz to jako drugorzędne sprzężenie lewe do zapytania, coś takiego jak

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

Jednakże, ponieważ jest to wynik kartezjański... wiele wierszy na każde połączenie pobiera wynik RAZY każdy wpis, który istnieje w innej tabeli... coś w stylu

Yr    AmtChange  COChangeAmt
2013  120         440
2014  180         840

Aby to naprawić, każda pojedyncza tabela, z której otrzymujesz sumy częściowe, powinna być obsługiwana osobno i pogrupowana według własnego roku, aby podzbiór zwracał tylko jeden wiersz na kontekst danych. Coś jak

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

Tak więc podzapytania zwrócą tylko 1 rekord dla odpowiedniego roku, który jest agregowany, a tym samym zapobiegną duplikowaniu kwot sum().



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Obiekt nie może zostać przekonwertowany na ciąg w MySQLi PHP

  2. MYSQL - Wstaw, jeśli tabela jest pusta

  3. Metoda wyceny PDO

  4. Jak sprawdzić, czy kolumna jest pusta lub null w MySQL?

  5. Ustaw limit i przesuń nieprawidłowe umieszczenie w zapytaniu