Сначала соберите сумму, затем присоединитесь. Как это:
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)
В том виде, в каком вы были, каждое value_in
будет объединяться с каждым совпадающим value_out
, умножая числа. Сначала вы должны объединиться, а затем присоединиться к one in-sum с one out-sum, и все будет отлично. Или это?
Что произойдет, если для данного (date, uid)
нет value_in
или value_out
? Или только value_in
или просто value_out
? Ваш запрос не удастся.
Я улучшил использование LEFT JOIN
вместо [INNER] JOIN
, но на самом деле вам нужен FULL OUTER JOIN
- одна из недостающих функций в MySQL.
Вы можете либо предоставить список дней в отдельной таблице и LEFT JOIN
в обеих таблицах к ней, либо вы можете обойти отсутствующую функцию два раза LEFT JOIN
и UNION
. Смотрите здесь пример .
Или Вы можете умножить свои value_out
на -1
UNION и объединить обе таблицы в одну сумму.
Но вы все равно не получите ни одного дня подряд без value_in
или value_out
, что нарушает ваше описание.
Итак, единственное чистое решение состоит в том, чтобы иметь таблицу со всеми (date, uid)
, которые вы хотите получить в результате, и LEFT JOIN
суммами table1
и table2
или * 1049. * три (отрицательные table2
) в под-выборе, а затем подвести итог.