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

combinando o resultado da consulta mysql SUM () usando a junção interna


Primeiro construa a soma, depois junte-se. Assim:
SELECT i.uid
      ,i.date
      ,i.v_in
      ,COALESCE(o.v_out, 0) AS v_out
      ,(i.v_in - COALESCE(o.v_out, 0)) AS balance
FROM (
    SELECT date
          ,uid
          ,SUM(value_in) AS v_in
    FROM   table1
    GROUP  BY 1,2
    ) i
LEFT JOIN (
    SELECT date
          ,uid
          ,SUM(value_out) AS v_out
    FROM   table2
    GROUP  BY 1,2
    ) o USING (date, uid)

Do jeito que você tinha, cada value_in seria combinado com cada value_out correspondente , multiplicando assim os números. Você deve agregar primeiro e depois participar de um soma com um out-sum e tudo é groovy. Ou é?

O que acontece se não houver value_in ou value_out para um determinado (date, uid) ? Ou apenas value_in Ou apenas value_out ? Sua consulta falhará.

Melhorei usando um LEFT JOIN em vez de [INNER] JOIN , mas o que você realmente quer é um FULL OUTER JOIN - um dos recursos ausentes no MySQL.

Você pode fornecer uma lista de dias em uma tabela separada e LEFT JOIN ambas as tabelas, ou você pode contornar o recurso ausente com duas vezes LEFT JOIN e UNION . Veja aqui por exemplo .

Ou você pode multiplicar seu value_out por -1 UNION ambas as tabelas juntas e construa uma soma.

Mas você ainda não obteria uma linha por um dia sem nenhum value_in ou value_out , o que viola sua descrição.

Portanto, a única solução limpa é ter uma tabela com todos os (date, uid) você quer no resultado e LEFT JOIN as somas de table1 e table2 para ele, ou UNION ALL os três (negativo table2 ) em uma sub-seleção e, em seguida, some.