Primero construye la suma, luego únete. Así:
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)
Tal como lo tenías, cada value_in
se combinaría con cada value_out
coincidente , multiplicando así los números. Debe agregar primero y luego unirse a uno en suma con uno out-sum y todo es maravilloso. ¿O lo es?
¿Qué sucede si no hay value_in
? o value_out
para un (date, uid)
dado ? O solo value_in
O simplemente value_out
? Su consulta fallará.
Mejoré usando un LEFT JOIN
en lugar de [INNER] JOIN
, pero lo que realmente quieres es una FULL OUTER JOIN
- una de las funciones que faltan en MySQL.
Puede proporcionar una lista de días en una tabla separada y LEFT JOIN
ambas tablas, o puede evitar la función que falta con dos veces LEFT JOIN
y UNION
. Ver aquí para un ejemplo
.
O podrías multiplicar tu value_out
por -1
UNIR ambas tablas y construir una suma.
Pero tú todavía no obtendría una fila por un día sin ningún value_in
o value_out
, que infringe su descripción.
Entonces, la única solución limpia es tener una tabla con todos los (date, uid)
desea en el resultado y LEFT JOIN
las sumas de table1
y table2
a él, o UNION ALL
los tres (negativo table2
) en una subselección y luego suma.