Как получить сумму в объединенной таблице при использовании group by - получение неверных результатов - PullRequest
0 голосов
/ 27 января 2020

У меня есть две таблицы orders и order_items. Мне нужно сгруппировать результаты по дням. Но мне также нужно получить сумму energy_used за каждый день из другой таблицы. Когда я пытаюсь сделать это, используя соединение, я получаю ошибку order_sum за каждый день. Не уверен, что я делаю не так.

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

Вот моя orders таблица

+----+-----------+---------+---------------------+
| id | order_sum | user_id | created_at          |
+----+-----------+---------+---------------------+
| 1  | 25.13     | 7       | 2020-01-25 09:13:00 |
| 2  | 14.00     | 5       | 2020-01-26 10:14:00 |
| 3  | 35.00     | 1       | 2020-01-27 11:13:00 |
+----+-----------+---------+---------------------+

А вот моя order_items таблица

+----+----------+-------------+---------------------+
| id | order_id | energy_used | created_at          |
+----+----------+-------------+---------------------+
| 1  | 1        | 65          | 2020-01-25 09:13:00 |
| 2  | 1        | 12          | 2020-01-25 09:13:00 |
| 3  | 2        | 70          | 2020-01-26 10:14:00 |
| 4  | 2        | 5           | 2020-01-26 10:14:00 |
| 5  | 3        | 0           | 2020-01-27 11:13:00 |
+----+----------+-------------+---------------------+

И это желаемый результат, которого я пытаюсь достичь

+---------------+-----------------+-------------------+---------------------+----------------+
| date_of_month | total_order_sum | total_energy_used | last_order_date     | last_order_sum |
+---------------+-----------------+-------------------+---------------------+----------------+
| 2020-01-25    | 25.13           | 77                | 2020-01-25 09:13:00 | 25.13          |
| 2020-01-26    | 14.00           | 75                | 2020-01-26 10:14:00 | 14.00          |
| 2020-01-27    | 35.00           | 0                 | 2020-01-27 11:13:00 | 35.00          |
+---------------+-----------------+-------------------+---------------------+----------------+

А вот мой запрос, который я пробовал, но Я получаю неправильные результаты, сумма заказа не рассчитывается правильно из-за моего соединения с таблицей order_items

SELECT
    DATE(orders.created_at) AS date_of_month,
    SUM(orders.order_sum) AS order_sum,
    order_items.energy_used
FROM
    orders
JOIN (
    select
        order_id,
        sum(energy_used) as energy_used
    from
        order_items
    group by
        date(created_at)
) as order_items on order_items.order_id = orders.id
JOIN (
    select
        max(created_at) as last_order_date,
        max(order_sum) as last_order_sum
    from
        orders
    order by created at desc
    limit 1
) as orders2 on orders2.id = orders.id
GROUP BY
    date_of_month

Ответы [ 2 ]

1 голос
/ 27 января 2020

Я понимаю, что вы хотите, чтобы за каждый день:

  • сумма order_items.energy_used для всех заказов, созданных в этот день
  • created_at и order_sum, которые соответствуют до последней order, созданной в этот день

Ваши данные выборки не очень характерны для этого - у них есть только один заказ в день. Также неясно, почему created_at повторяется в обеих таблицах; вы действительно должны полагаться на order_id, чтобы связать обе таблицы

Вот запрос для вышеуказанной цели: он работает, объединяя таблицу orders с совокупным запросом, который вычисляет общую энергию в день ( используя order_id, чтобы получить created_at дату от orders), и фильтрует по последнему заказу в день:

select 
    date(o.created_at) date_of_month,
    i.total_energy_used,
    o.created_at last_order_date,
    o.order_sum last_order_sum
from orders o
inner join (
    select date(o1.created_at) date_of_month, sum(i1.energy_used) total_energy_used
    from orders o1
    inner join order_items i1 on o1.id = i1.order_id
    group by date(o1.created_at)
) i on i.date_of_month = date(o.created_at)
where o.created_at = (
    select max(o1.created_at)
    from orders o1
    where date(o1.created_at) = date(o.created_at)
)

Демонстрация на DB Fiddle :

date_of_month | total_energy_used | last_order_date     | last_order_sum
:------------ | ----------------: | :------------------ | -------------:
2020-01-25    |                77 | 2020-01-25 09:13:00 |          25.13
2020-01-26    |                75 | 2020-01-26 10:14:00 |          14.00
2020-01-27    |                 0 | 2020-01-27 11:13:00 |          35.00
0 голосов
/ 27 января 2020

Если я правильно понимаю, вы просто хотите выделить энергию для последнего дня месяца. Если так:

SELECT DATE(o.created_at) AS date_of_month,
       SUM(oi.energy_used) AS order_sum,
       MAX(o.created_at) as last_order_date,
       SUM(CASE WHEN d.max_ca = o.created_at THEN oi.energy_used END) as max_energy_used
FROM orders o JOIN
     order_items oi
     ON oi.order_id = o.id JOIN
     (SELECT DATE(o.created_at) as date_ca, MAX(o.created_at) as max_ca
      FROM orders o
      GROUP BY DATE(o.created_at)
     ) d
     ON DATE(o.created_at) = d.date_ca
GROUP BY date_of_month
...