Mysql Left Join And Sum не работает правильно с группой по месяцам и годам

0

Я хочу получить сумму total_amount и received_amt с группой по месяцам и годам на mysql. Но я столкнулся с проблемой. Проблема заключается в том, что сумма столбцов второй таблицы не соответствует группе по месяцам и годам.

Текущий запрос

SELECT t1.order_date,sum(IFNULL(t1.received_amt, 0)) as SumOfNO,
sum(IFNULL(t2.total_amount, 0)) as SumOfSM,
SUM(IFNULL(t1.received_amt, 0)  + IFNULL(t2.total_amount, 0)) AS Total
FROM 'new_order' t1
LEFT JOIN
 (  select t2.sell_date,t2.total_amount, sum(total_amount) as Amount
    from sell_master t2
    group by YEAR(t2.sell_date), MONTH(t2.sell_date) 
 ) t2
 ON format(t1.order_date,'yyyy-MM') = format(t2.sell_date,'yyyy-MM')
GROUP BY YEAR(t1.order_date), MONTH(t1.order_date)
ORDER BY t1.order_date DESC

Пример:

Первая таблица: new_order

Вторая таблица: sell_master

Структура таблицы:

новый порядок

+----------------------------------------+
|order_date(date) | received_amt(double) |
+----------------------------------------+
|2007-10-06       | 245                  |
|2007-10-06       | 310                  |                             
|2007-10-06       | 275                  |                             
|2007-10-06       | 300                  |
+----------------------------------------+

sell_master

+----------------------------------------+
|sell_date(date)  | total_amount(double) |
+----------------------------------------+
|2007-10-06       | 10                   |
+----------------------------------------+

Текущий результат

+---------------------------------------+
|order_date | SumOfNO | SumOfSM | Total |
+---------------------------------------+
|2007-10-06 | 1130    | 40      |1170   |
+---------------------------------------+

ожидаемый результат

+---------------------------------------+
|order_date | SumOfNO | SumOfSM | Total |
+---------------------------------------+
|2007-10-06 | 1130    | 10      |1140   |
+---------------------------------------+
  • 0
    Ваш подзапрос скорее всего просто плохой; Поля sell_date и total_amount в его результатах будут фактически случайным выбором из значений, найденных в записях для группировки пар год-месяц. Почему вы даже рассчитываете Amount когда она фактически не используется?
  • 0
    Вы группируете по месяцам и годам, поэтому вы получаете одну строку результатов в месяц и год. Почему вы выбираете дату тогда? Какой датой это должно быть? Таким образом, MySQL пропустит это и выберет произвольную дату в каждом месяце, но не лучше ли выбрать год и месяц вместо такой даты?
Показать ещё 1 комментарий
Теги:
join
sum
left-join
multiple-columns

2 ответа

1
Лучший ответ

Вы не должны использовать SUM(t2.total_amount) в основном запросе. Вы уже рассчитали сумму в подзапросе, вы должны использовать это. t2.total_amount что вы умножаете t2.total_amount на количество строк в new_order которое соответствует.

Также нет необходимости использовать IFNULL() внутри SUM(), поскольку SUM() игнорирует нулевые значения (большинство функций агрегации делают).

Подзапрос должен выбрать год и месяц даты, поэтому вы можете присоединиться к этой директории, а не использовать date_format.

И так как вы группируете по месяцам, вам не следует выбирать t1.order_date - это будет просто выбрать случайный день месяца из группы. Вы должны просто показать месяц в YYYY-MM.

SELECT 
    DATE_FORMAT(t1.order_date, '%Y-%m') AS month,
    sum(t1.received_amt) as SumOfNO,
    IFNULL(t2.Amount, 0) as SumOfSM,
    sum(t1.received_amt) + IFNULL(t2.Amount, 0) AS Total
FROM 'new_order' t1
LEFT JOIN
 (  select YEAR(t2.sell_date) AS year, MONTH(t2.sell_date) AS month,  sum(total_amount) as Amount
    from sell_master t2
    group by year, month
 ) t2
 ON YEAR(t1.order_date) = t2.year AND MONTH(t1.order_date) = month
GROUP BY month
ORDER BY month DESC

DEMO

  • 0
    хорошая попытка @Barmar, но извините, моя первая сумма в таблице неверна, а вторая сумма в таблице верна.
  • 0
    Я только что добавил демонстрационную ссылку, она возвращает ожидаемый ответ.
Показать ещё 1 комментарий
0

Вы хотите выбрать совокупные результаты (суммы здесь) одной таблицы в сочетании с совокупными результатами другого. Поэтому создайте оба агрегата, затем присоединитесь.

select 
  year_month, 
  o.total as sumofno,
  coalesce(s.total, 0) as sumofsm,
  o.total + coalesce(s.total, 0) as total
from
(
  select format(order_date, 'yyyy-MM') as year_month, sum(received_amt) as total
  from new_order
  group by format(order_date, 'yyyy-MM')
) o
left join
(
  select format(sell_date, 'yyyy-MM') as year_month, sum(total_amount) as total
  from sell_master
  group by format(sell_date, 'yyyy-MM')
) s using (year_month)
order by month desc;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню