Вывести данные из двух таблиц в одну строку с суммированием значений и разбиением по дням
Есть две таблицы. В одной начисления, в другой списания баланса. Нужно в одну строку вывести значения из обеих таблиц для заданного пользователя в определенном интервале. За определенный интервал в одной таблице могут быть значения, а в другой может не быть. Во второй таблице нужно сложить списания за день. И выводить даты. Важно не суммировать значения в первой таблице. Поскольку зачисления могут быть их разных источников, а списание всегда из одного.
Может быть и так, что нет ни начислений, ни списаний за день. Тогда вывести пустую строку с датой. Если это вообще возможно.
Возможно ли это вообще сделать на чистом sql или нужно будет обрабатывать програмно и собирать нужный массив?
Пример первой таблицы:
| Логин | Сумма | Комментарий | Дата |
|---|---|---|---|
| user | 500 | Зачисление | 2022-08-24 |
| user | 7000 | Зачисление №2 | 2022-08-25 |
| user | 1000 | Зачисление | 2022-08-25 |
Вторая таблица
| Логин | Сумма | Комментарий | Дата |
|---|---|---|---|
| user | -10 | Списание | 2022-08-24 |
| user | -20 | Списание | 2022-08-24 |
| user | -30 | Списание | 2022-08-24 |
| user | -100 | Списание | 2022-08-26 |
| user | -200 | Списание | 2022-08-26 |
| user | -300 | Списание | 2022-08-26 |
Результат
| Логин | Зачисление | Списание | Дата |
|---|---|---|---|
| user | 500 | -60 | 2022-08-24 |
| user | 700 | -60 | 2022-08-24 |
| user | 1000 | null | 2022-08-25 |
| user | null | -600 | 2022-08-26 |
Ответы (2 шт):
Возможно это то, что вам нужно:
select b.login,t1.summa as zachislenie,sum(distinct t2.summa) as spisanie,b.data
from (
select distinct login,data from (
SELECT distinct login,data from table1
union all
SELECT distinct login,data from table2
) a
) b left join table1 t1 on b.data=t1.data left join table2 t2
on b.data=t2.data group by b.login,b.data,t1.summa
В MySQL нет FULL JOIN-ов, поэтому вот так:
CREATE TABLE income (login VARCHAR(255), amount REAL, note VARCHAR(255), ddate DATETIME);
INSERT INTO income (login, amount, note, ddate) VALUES
('user', 500, 'Зачисление', '2022-08-24'),
('user', 7000, 'Зачисление №2', '2022-08-25'),
('user', 1000, 'Зачисление', '2022-08-25');
CREATE TABLE outcome (login VARCHAR(255), amount REAL, note VARCHAR(255), ddate DATETIME);
INSERT INTO outcome (login, amount, note, ddate) VALUES
('user', -10, 'Списание', '2022-08-24'),
('user', -20, 'Списание', '2022-08-24'),
('user', -30, 'Списание', '2022-08-24'),
('user', -100, 'Списание', '2022-08-26'),
('user', -200, 'Списание', '2022-08-26'),
('user', -300, 'Списание', '2022-08-26');
SELECT
CASE WHEN i.login IS NULL THEN o.login ELSE i.login END AS login,
SUM(i.amount) AS amount_i,
SUM(o.amount) AS amount_o,
CASE WHEN i.ddate IS NULL THEN o.ddate ELSE i.ddate END AS ddate
FROM income i
LEFT JOIN outcome o ON o.ddate = i.ddate
GROUP BY i.login, o.login, i.ddate, o.ddate
UNION
SELECT
CASE WHEN i.login IS NULL THEN o.login ELSE i.login END AS login,
SUM(i.amount) AS amount_i,
SUM(o.amount) AS amount_o,
CASE WHEN i.ddate IS NULL THEN o.ddate ELSE i.ddate END AS ddate
FROM income i
RIGHT JOIN outcome o ON o.ddate = i.ddate
GROUP BY i.login, o.login, i.ddate, o.ddate;
DROP TABLE income;
DROP TABLE outcome;