Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
248 views
in Technique[技术] by (71.8m points)

mysql - How to get the sum in a joined table when using group by - getting wrong results

I have two tables orders and order_items. I need to group the results by days. But I also need to get the sum of energy_used for each day from another table. When I try that using a join, I get wrong order_sum for each day. Not sure what I am doing wrong.

I am using joins because I would also like to sort by these columns later.

Here is my orders table

+----+-----------+---------+---------------------+
| 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 |
+----+-----------+---------+---------------------+

And here is my order_items table

+----+----------+-------------+---------------------+
| 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 |
+----+----------+-------------+---------------------+

And this is the desired result that I am trying to achieve

+---------------+-----------------+-------------------+---------------------+----------------+
| 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          |
+---------------+-----------------+-------------------+---------------------+----------------+

And here is my query that I have tried but I'm getting wrong results, the order_sum is not being calculated correctly because of my join with the order_items table

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I understand that you want, for each day:

  • the sum of order_items.energy_used for all orders created that day
  • the created_at and order_sum that correspond to the latest order created on that day

Your sample data is not very representative of that - it has only one order per day. Also it is unclear why created_at is repeated in both tables; you should really be relying on the order_id to relate both tables

Here is a query for the above purpose: this works by joining the orders table with an aggregate query that computes the total energy per day (using order_id to get the created_at date from orders), and filters on the latest order per day:

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)
)

Demo on 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...