【问题标题】:mysql with rollup discrepancy具有汇总差异的mysql
【发布时间】:2018-06-06 16:10:18
【问题描述】:

我在 MySQL 中遇到了 WITH ROLLUP 的一个奇怪问题,我无法理解。我有一个餐厅订单数据库,根据查询的组合方式,它在底部给出了不同的总数。

以下查询计算正确,并使用SUM(m.price*od.qty)

SELECT m.item_name, m.price, SUM(od.qty), COUNT(*), SUM(m.price*od.qty) 
FROM order_main AS om, order_detail AS od, menu as m 
WHERE od.menuid=m.menuid AND om.orderid=od.orderid AND om.order_date='2012-11-16' AND m.menuid<10 
GROUP BY m.menuid WITH ROLLUP;
+-------------------+-------+-------------+----------+---------------------+
| item_name         | price | SUM(od.qty) | COUNT(*) | SUM(m.price*od.qty) |
+-------------------+-------+-------------+----------+---------------------+
| Cheese Sticks     |  8.74 |          31 |       11 |              270.94 |
| Pepper Pasta      |  1.63 |          55 |       18 |               89.65 |
| Sambuca Puree     |  2.84 |          68 |       22 |              193.12 |
| Beef Tenderloin   |  2.52 |          48 |       16 |              120.96 |
| Pork Chops        |  5.37 |          53 |       18 |              284.61 |
| Sole Nole         |  2.13 |          65 |       18 |              138.45 |
| Nescafe Espresso  |  9.96 |          56 |       21 |              557.76 |
| Lettuce Wraps     |  8.35 |          57 |       21 |              475.95 |
| Bread with Butter |  9.36 |          55 |       19 |              514.80 |
| WITH ROLLUP       |  ---- |         488 |      164 |             2646.24 |
+-------------------+-------+-------------+----------+---------------------+

以下查询使用m.price*SUM(od.qty) 计算的汇总不正确。但其他一切都在表格中。

SELECT m.item_name, m.price, SUM(od.qty), COUNT(*), m.price*SUM(od.qty) 
FROM order_main AS om, order_detail AS od, menu as m 
WHERE od.menuid=m.menuid AND om.orderid=od.orderid AND om.order_date='2012-11-16' AND m.menuid<10 
GROUP BY m.menuid WITH ROLLUP;
+-------------------+-------+-------------+----------+---------------------+
| item_name         | price | SUM(od.qty) | COUNT(*) | m.price*SUM(od.qty) |
+-------------------+-------+-------------+----------+---------------------+
| Cheese Sticks     |  8.74 |          31 |       11 |              270.94 |
| Pepper Pasta      |  1.63 |          55 |       18 |               89.65 |
| Sambuca Puree     |  2.84 |          68 |       22 |              193.12 |
| Beef Tenderloin   |  2.52 |          48 |       16 |              120.96 |
| Pork Chops        |  5.37 |          53 |       18 |              284.61 |
| Sole Nole         |  2.13 |          65 |       18 |              138.45 |
| Nescafe Espresso  |  9.96 |          56 |       21 |              557.76 |
| Lettuce Wraps     |  8.35 |          57 |       21 |              475.95 |
| Bread with Butter |  9.36 |          55 |       19 |              514.80 |
| WITH ROLLUP       |  ---- |         488 |      164 |             4567.68 |
+-------------------+-------+-------------+----------+---------------------+

我找不到任何关于 WITH ROLLUP 计算方式不同的原因,尤其是因为每件商品的价格都是静态的。

【问题讨论】:

  • 这两个查询是相同的。 “基于查询的组合方式”是什么意思?
  • 您需要 WITH ROLLUP 吗? - 我从来没有真正找到它的用途。
  • @Barmar 抱歉,我复制粘贴有点匆忙。现在更新了。

标签: mysql rollup


【解决方案1】:

您正在使用 MySQL 最棘手的功能之一:包括既不属于 group by 也不以某种方式聚合的字段。在您的情况下,m.price 和 MySQL 将使用它遇到的第一个值。由于任何原因,这可能在执行之间有所不同。在较新的版本中,默认情况下已禁用此功能,因为它可能会导致这种意外结果。

所以你的第二个公式 m.price * SUM(od.qty) 本质上意味着: “对于每个组(菜单项),取您为 m.price 找到的第一个值,并将其乘以该组中数量的总和”。

这适用于商品,因为每个商品只有一个价格,但对于汇总,您会从整个数据集中获得一个随机价格。

将分组更正为“m.menuid, m.price”或使用像 AVG() 这样的聚合。

【讨论】:

  • 说的有道理,但还是有点混乱。商品价格与每件商品相关联,如果我们按menuid 分组,那么应该为每一行拉取它,因为它是一对一的。
  • @fiddlestacks 这是在你分组的时候,但汇总不再按菜单项分组,所以你得到一个“半随机”的。您的示例结果显示,最后一个值 (9.36) 乘以总量 (488)。
  • @Cyrus 考虑WITH ROLLUP 的方式是通过从GROUP BY 的末尾删除一列并执行该查询来创建每个级别的小计。总计是没有GROUP BY 的原始查询。
猜你喜欢
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 2020-09-12
相关资源
最近更新 更多