MySQL с несоответствия накопления - PullRequest
0 голосов
/ 06 июня 2018

Я столкнулся со странной проблемой с WITH ROLLUP в MySQL, которую мне трудно понять.У меня есть база данных заказов для ресторана, и она показывает мне разные итоги в нижней части в зависимости от того, как составлен запрос.

Приведенный ниже запрос рассчитан правильно и использует 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 рассчитывает по-разному, особенно с учетом того, что цена каждого элемента является статической.

1 Ответ

0 голосов
/ 06 июня 2018

Вы используете одну из самых хитрых функций MySQL: включая поля, которые ни в группе, ни каким-либо образом не агрегированы.В вашем случае это m.price , и MySQL будет использовать первое обнаруженное значение.Это может отличаться между казнями по любой причине.В более новых версиях это было отключено по умолчанию, так как это может привести именно к такому типу неожиданного результата.

Таким образом, ваша вторая формула m.price * SUM (od.qty) по существу означает: «Для каждой группы(пункт меню) возьмите первое значение, которое вы найдете для m.price, и умножьте его на сумму количества в этой группе ".

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

Исправьте группу, сказав "m.menuid, m.price" или используйте агрегацию, например AVG ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...