объединение результата запроса mysql SUM () с использованием внутреннего соединения - PullRequest
2 голосов
/ 03 ноября 2011

У меня есть эти две таблицы

table1 : date | uid | value_in
table2 : date | uid | value_out 

каждый день, каждый пользователь будет получать значение баланса для входа и выхода, независимо от количества транзакций / записей

я хочу объединить результат запроса так, как это

date | uid | value_in | value_out | (value_in-value_out) as balance

однако, когда я делаю этот запрос

SELECT 
  a.date,
  a.uid,
  SUM(a.value_in),
  SUM(b.value_out),
  (SUM(a.value_in)-SUM(b.value_out)) AS balance
FROM table1 a
INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
GROUP BY a.date, a.uid

это дает неверный результат (SUM удваивается или утраивается) как мне изменить мой запрос, чтобы он не давал двойной результат?

Ответы [ 3 ]

3 голосов
/ 03 ноября 2011

Сначала соберите сумму, затем присоединитесь. Как это:

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) в под-выборе, а затем подвести итог.

0 голосов
/ 27 декабря 2012
SELECT 
  a.date,
  a.uid,
  SUM(a.value_in),
  SUM(b.value_out),
  SUM(a.value_in-b.value_out) AS balance 
FROM table1 a
INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
GROUP BY a.date, a.uid`enter code here`
0 голосов
/ 03 ноября 2011

Что будет, если вы попробуете это

SELECT 
  a.date,
  a.uid,
  SUM(a.value_in),
  SUM(b.value_out),
  SUM(a.value_in-b.value_out) AS balance 
FROM table1 a
INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
GROUP BY a.date, a.uid

SUM(a.value_in-b.value_out) AS balance должно быть логически таким же, как (SUM(a.value_in)-SUM(b.value_out)) AS balance, но, возможно, не MySQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...