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.