Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Múltiplas Junções Esquerdas com Soma


O problema pode ser o fato devido a um resultado cartesiano de seus dados e somatórios acontecendo. Só para esclarecer, aqui está uma consulta simples... Eu sei que não tenho tudo, nem juntar colunas perfeitas, isso é apenas para esclarecimento.

TAMBÉM, SEI que abreviei as colunas e aliases para simplificar a leitura e a compreensão do conceito do que você provavelmente 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

No final, sem problemas... para um determinado ano, você obterá os totais da segunda tabela. Existem muitos registros na tabela 2. Ex:Dados
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

Provavelmente concordamos com isso neste ponto... Agora, coloque outra tabela que por ano (ou qualquer outra coisa), que também tenha vários registros por ano...
Change_Orders
Yr     COAmt
2013   100
2013   120
2014   200
2014   220

E você adiciona isso como uma junção esquerda secundária à sua consulta, algo 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

No entanto, como é um resultado cartesiano ... várias linhas por cada junção estão obtendo os resultados VEZES cada entrada que existe na outra tabela ... algo como
Yr    AmtChange  COChangeAmt
2013  120         440
2014  180         840

Para corrigir isso, cada tabela individual da qual você está obtendo subtotais deve ser tratada por conta própria e agrupada por seu próprio ano para que o subconjunto retorne apenas uma linha por contexto de dados. 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

Assim, cada subconsulta retornará apenas 1 registro para o respectivo ano sendo agregado e, assim, evitará a duplicação de valores de sum().