Prima costruisci la somma, quindi unisciti. In questo modo:
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)
Il modo in cui lo avevi, ogni value_in
verrebbe combinato con ogni value_out
corrispondente , moltiplicando così i numeri. Devi prima aggregare e poi unirti a uno somma con uno out-sum e tutto è groovy. O lo è?
Cosa succede se non ci sono value_in
o value_out
per un dato (date, uid)
? O solo value_in
O semplicemente value_out
? La tua richiesta avrà esito negativo.
Sono migliorato utilizzando un LEFT JOIN
invece di [INNER] JOIN
, ma quello che vuoi veramente è un FULL OUTER JOIN
- una delle funzionalità mancanti in MySQL.
Puoi fornire un elenco di giorni in una tabella separata e LEFT JOIN
entrambe le tabelle, oppure puoi aggirare la funzione mancante con due volte LEFT JOIN
e UNION
. Vedi qui per un esempio
.
Oppure potresti moltiplicare il tuo value_out
per -1
UNION entrambe le tabelle insieme e costruisci una somma.
Ma tu ancora non otterrebbe una riga per un giorno senza alcun value_in
o value_out
, che viola la tua descrizione.
Quindi, l'unica soluzione pulita è avere una tabella con tutti i (date, uid)
vuoi nel risultato e LEFT JOIN
le somme di table1
e table2
ad esso, o UNION ALL
i tre (table2
negativo ) in una sottoselezione e poi riepiloga.