Bygg först summan, gå sedan med. Så här:
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)
Som du hade det, varje value_in
skulle kombineras med varje matchande value_out
, och därigenom multiplicera siffrorna. Du måste först sammanställa och sedan gå med i ett i-summa med ett slutsumma och allt är groovy. Eller är det?
Vad händer om det inte finns någon value_in
eller value_out
för en given (date, uid)
? Eller bara value_in
Eller bara value_out
? Din fråga kommer att misslyckas.
Jag förbättrade mig genom att använda en LEFT JOIN
istället för [INNER] JOIN
, men vad du verkligen vill ha är en FULL OUTER JOIN
- en av de saknade funktionerna i MySQL.
Du kan antingen tillhandahålla en lista över dagar i en separat tabell och LEFT JOIN
båda tabellerna till den, eller så kan du kringgå den saknade funktionen med två gånger LEFT JOIN
och UNION
. Se här till exempel
.
Eller du kan multiplicera ditt value_out
av -1
FÖRENA båda tabellerna tillsammans och bygg en summa.
Men du fortfarande skulle inte få en rad för en dag utan någon value_in
eller value_out
, vilket bryter mot din beskrivning.
Så den enda rena lösningen är att ha en tabell med alla (date, uid)
du vill ha i resultatet och LEFT JOIN
summan av table1
och table2
till den, eller UNION ALL
de tre (negativa table2
) i ett underval och summera sedan.