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

Kombinieren des Ergebnisses der MySQL-Abfrage SUM () mit innerer Verknüpfung

Erst die Summe aufbauen, dann mitmachen. So:

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)

So wie Sie es hatten, jeder value_in würde mit jedem passenden value_out kombiniert werden , wodurch die Zahlen multipliziert werden. Sie müssen zuerst aggregieren und dann einem beitreten in Summe mit eins out-sum und alles ist groovy. Oder doch?

Was passiert, wenn value_in nicht vorhanden ist oder value_out für einen gegebenen (date, uid) ? Oder nur value_in Oder einfach value_out ? Ihre Abfrage wird fehlschlagen.

Ich habe mich verbessert, indem ich einen LEFT JOIN verwendet habe statt [INNER] JOIN , aber was Sie wirklich wollen, ist ein FULL OUTER JOIN - eines der fehlenden Features in MySQL.

Sie können entweder eine Liste der Tage in einer separaten Tabelle und LEFT JOIN bereitstellen beide Tabellen dazu, oder man umgeht das fehlende Feature mit zweimal LEFT JOIN und UNION . Siehe hier zum Beispiel .

Oder Sie könnten Ihren value_out multiplizieren durch -1 UNION beide Tabellen zusammen und bildet eine Summe.

Aber Sie noch würde einen Tag lang keine Zeile ohne value_in erhalten oder value_out , was gegen Ihre Beschreibung verstößt.

Also die einzig saubere Lösung soll eine Tabelle mit allen (date, uid) haben Sie wollen im Ergebnis und LEFT JOIN die Summen von table1 und table2 dazu oder UNION ALL die drei (negative table2 ) in einer Unterauswahl und dann zusammenfassen.