Byg først summen, kom så med. Sådan:
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 havde det, hver value_in ville blive kombineret med hver matchende value_out , hvorved tallene ganges. Du skal først samle og derefter tilslutte dig én i-sum med én out-sum og alt er groovy. Eller er det?
Hvad sker der, hvis der ikke er nogen value_in eller value_out for en given (date, uid) ? Eller kun value_in Eller bare value_out ? Din forespørgsel vil mislykkes.
Jeg forbedrede mig ved at bruge en LEFT JOIN i stedet for [INNER] JOIN , men hvad du virkelig ønsker, er en FULL OUTER JOIN - en af de manglende funktioner i MySQL.
Du kan enten angive en liste over dage i en separat tabel og LEFT JOIN begge tabeller til det, eller du kan omgå den manglende funktion med to gange LEFT JOIN og UNION . Se her for et eksempel
.
Eller du kan gange din value_out med -1 FORBIND begge tabeller sammen og byg en sum.
Men du stadig ville ikke få en række i en dag uden nogen value_in eller value_out , hvilket overtræder din beskrivelse.
Så den eneste rene løsning er at have en tabel med alle (date, uid) du vil have i resultatet og LEFT JOIN summen af table1 og table2 til det, eller UNION ALL de tre (negativ table2 ) i et undervalg og opsummer derefter.