Расчет, суммирование и группировка по 3-м таблицам - PullRequest
1 голос
/ 09 июля 2020

У меня есть 4 таблицы: предметы, заказы, inventory_item и inventory. Они структурированы следующим образом:

 _________         ____________         ________________         _____________
| orders  | >---- |  items     | ----< | inventory_item | >---- | inventories |
|- - - - -|       |- - - - - - |       |- - - - - - - - |       |- - - - - - -|
|+item_id |       |+id         |       |+id             |       |+id          |
|+amount  |       |+group_id   |       |+inventory_id   |        -------------
 ---------        |+worth      |       |+item_id        |       
                  |+min_amount |       |+amount         |
                   ------------         ----------------

Таблица инвентаризации не требует запросов и отображается только для понимания структуры.

Я хотел бы иметь один запрос sql, который совместим с MariaDB и выполняет следующие функции: сгруппирован по инвентарю и отображению group_id:

  • SUM (orders.amount)
  • SUM (items.min_amount)
  • SUM (inventory_item.amount)
  • SUM (items.worth * inventory_item.amount)

Я попытался поработать над этим с помощью подзапросов, но это казалось безнадежным. Моя текущая попытка выглядит так:

SELECT
    `inventory_item`.`inventory_id`,
    `items`.`group_id`,
    SUM(`items`.`min_amount`),
    SUM(`inventory_item`.`amount`),
    SUM(`inventory_item`.`amount` * `items`.`worth`),
    SUM(`orders`.`amount`)
FROM `items`
INNER JOIN `inventory_item` ON `items`.`id` = `inventory_item`.`item_id`
LEFT JOIN `orders` ON `items`.`id` = `orders`.`item_id`
GROUP BY
    `inventory_item`.`inventory_id`,
    `items`.`group_id`

Значение SUM (orders.amount) действительно правильное, но другие ошибочные, потому что один элемент считается несколько раз.

Я знаю, как чтобы решить эту проблему с помощью нескольких запросов, но я хотел бы сделать это только с одним (совместимым с MariaDB) запросом sql. Есть идеи, как это сделать?

1 Ответ

1 голос
/ 09 июля 2020

Что вам нужно, так это предварительно агрегировать результаты по одному из измерений. Я думаю, вы можете сделать это путем предварительного агрегирования orders:

SELECT ii.inventory_id, i.group_id,
       SUM(i.min_amount),
       SUM(ii.amount),
       SUM(ii.amount * i.worth),
       SUM(i.amount)
FROM items i JOIN
     inventory_item ii
     ON i.id` = ii.item_id LEFT JOIN
     (SELECT o.item_id, SUM(o.amount) as amount
      FROM orders o
      GROUP BY o.item_id
     ) o
     ON o.item_id = i.id
GROUP BY ii.inventory_id, i.group_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...