Сумма двух столбцов из двух таблиц без декартовой - PullRequest
0 голосов
/ 24 марта 2020

Я искал некоторое время, но ничего, что я нашел, не решает мою проблему ...

У меня есть две таблицы: доходы, расходы

У меня есть столбцы:

  • доход.счет
  • доход.дата
  • расходов.сумма
  • расходов.дата

Я хочу суммировать все свои доход и показать их по годам и месяцам, так что я делаю это, и он отлично работает ...

SELECT
     DATE_FORMAT(date, '%Y%m') AS 'date',
     SUM(amount) as 'total_earnings'
FROM earnings
GROUP BY DATE_FORMAT(date, '%Y%m')

Вывод похож на это ...

date,total_earnings
201901,5000
201902,5500
201903,6200
etc.

Я делаю то же самое для таблицы расходов, и все хорошо.

Моя проблема: Когда я пытаюсь написать запрос, который показывает мне общий доход и общие расходы, сгруппированные по годам и месяцам, я получаю декартову результат показывает цифры huuuge.

Это пример запроса, который показывает декартовой результат:

SELECT
    DATE_FORMAT(ea.date, '%Y%m') AS date,
    SUM(ea.amount) AS 'total_earnings',
    SUM(ex.amount) AS 'total_expenses',
FROM earnings ea
    INNER JOIN expenses ex
        ON DATE_FORMAT(ea.date, '%Y%m') = DATE_FORMAT(ex.date, '%Y%m')
GROUP BY DATE_FORMAT(ex.date, '%Y%m')

Как я могу показать общую сумму ежемесячных доходов и ежемесячных расходов в одном запросе?

Желаемый вывод:

date,total_earnings,total_expenses
201901,5000,1000
201902,5500,1100
201903,6200,1250

Заранее спасибо!

Ответы [ 3 ]

1 голос
/ 24 марта 2020

Сначала нужно агрегировать, затем JOIN

SELECT ea.date, total_earnings, total_expenses
FROM (
    SELECT DATE_FORMAT(date, '%Y%m') AS date
        , SUM(amount) AS total_earnings
    FROM earnings 
    GROUP BY DATE_FORMAT(date, '%Y%m')
) ea
JOIN (
    SELECT DATE_FORMAT(date, '%Y%m') AS date
        , SUM(amount) AS total_expenses
    FROM expenses
    GROUP BY DATE_FORMAT(date, '%Y%m')
) ex ON ex.date = ea.date
0 голосов
/ 24 марта 2020

Вы можете добиться этого, используя подзапрос:

SELECT `date`, SUM(earnings) AS total_earnings, SUM(expenses) AS total_expenses
FROM (
         SELECT DATE_FORMAT(earnings.date, '%Y%m') AS `date`, `amount` AS earnings, 0 AS expenses
         FROM earnings
         UNION
         SELECT DATE_FORMAT(expenses.date, '%Y%m') AS `date`, 0 AS earnings, `amount` AS expenses
         FROM expenses
     ) expenses_earnings
GROUP BY `date`

Редактировать:

Используя YEAR(date) и MONTH(date) вместо DATE_FORMAT, что позволит вам вычислить общее количество каждого года и итоговой суммы с использованием накопительного пакета.

SELECT `year`, `month`, SUM(earnings) AS total_earnings, SUM(expenses) AS total_expenses
FROM (
         SELECT YEAR(earnings.date) AS `year`, MONTH(earnings.date) AS `month`, `amount` AS earnings, 0 AS expenses
         FROM earnings
         UNION
         SELECT YEAR(expenses.date) AS `year`, MONTH(expenses.date) AS `month`, 0 AS earnings, `amount` AS expenses
         FROM expenses
     ) expenses_earnings
GROUP BY `year`, `month`
0 голосов
/ 24 марта 2020

Возможно, вам не нужно объединение ..

drop table if exists t;
create table t
(expense_amount int,expense_date date, earnings_amount int, earnings_date date);

insert into t values
(10,'2020-01-01',null,null),
(10,'2020-01-01',null,null),
(10,'2020-02-01',null,null),
(null,null,10,'2020-01-01'),
(10,'2020-03-01',10,'2020-03-01');


select coalesce(expense_date,earnings_date) date,
         sum(case when expense_amount is not null then expense_amount else 0 end) expense,
         sum(case when earnings_amount is not null then earnings_amount else 0 end) earnings
from t
group by coalesce(expense_date,earnings_date);

+------------+---------+----------+
| date       | expense | earnings |
+------------+---------+----------+
| 2020-01-01 |      20 |       10 |
| 2020-02-01 |      10 |        0 |
| 2020-03-01 |      10 |       10 |
+------------+---------+----------+
3 rows in set (0.001 sec)

Если ваша модель данных отличается в этой строке, может содержать расходы и доходы с разными датами, тогда это не сработает для вас и для вас должны генерировать итоги отдельно и присоединиться к ним.

...