【问题标题】:How to get the sum in a joined table when using group by - getting wrong results使用 group by 时如何在连接表中获取总和 - 得到错误的结果
【发布时间】:2020-05-12 21:34:05
【问题描述】:

我有两张桌子ordersorder_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 表,order_sum 没有被正确计算

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

【问题讨论】:

  • 您使用的是哪个版本的 MySQL?
  • @GMB 我使用的是 5.5 版
  • 一个好的“经验法则”是,如果非聚合列出现在 SELECT 中,那么它也必须出现在 GROUP BY 中。
  • last_order_sum的逻辑是什么?
  • @GordonLinoff last_order_sum 是从订单表中取出 max(created_at) 的 sum(order_sum)

标签: mysql sql database group-by


【解决方案1】:

我了解您希望每天:

  • 当天创建的所有订单的order_items.energy_used 总和
  • created_atorder_sum 对应于当天创建的最新 order

您的示例数据并不能很好地代表这一点 - 它每天只有一个订单。也不清楚为什么created_at 在两个表中都重复;你真的应该依靠order_id 来关联两个表

这是一个用于上述目的的查询:通过将orders 表与计算每天总能量的聚合查询连接起来(使用order_idorders 获取created_at 日期),并过滤每天的最新订单:

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

【讨论】:

  • 每天只缺少order_sum,因为一天可以有很多订单
  • @Liga:我不清楚。 last_order_sum 是每天最后 个订单的order_sum,还是当天所有order_sums 的总和?正如我所说,您的样本数据每天只有一个订单,因此我必须做出假设,这些假设在我的回答中进行了详细说明。
  • last_order_sum 是每天最后一个订单的 order_sum - 正确。抱歉,我忘了说我还想每天获取order_sum ..(所以一天可以有很多订单,所以要获取每天的总order_sum)。更新了问题。
  • @Liga:在发布答案后对问题进行实质性修改并不是一个好的做法。我会推荐accepting the answer that best responded to your question 并提出一个 问题以及相关的示例数据。
  • 好的,谢谢,我会的。我不知何故遗漏了一个小细节......
【解决方案2】:

如果我理解正确,您只是想分离出该月最后一天的能量。如果是这样:

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

【讨论】:

  • 嗯,我想为每天的订单获取每天使用的总能量
  • @Liga 。 . .这个查询就是这样做的。
  • 哦,我明白了,我弄错了energy_used 我没有得到每天使用的所有能量的总和..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 2013-08-14
  • 2012-04-23
相关资源
最近更新 更多