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.