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.