2014-08-01 6 views
0

У меня есть два запроса: оба поставляют инвентарь, инвентарь.title и сумму, необходимую для заказов.Можно ли объединить эти комплексные запросы MYSQL?

Что я хотел бы сделать, это объединить их, чтобы результаты столбца amount_needed_for_orders суммировались вместе.

Вот краткое описание происходящего. Я работаю над программой управления запасами хлебобулочных изделий. У пекаря есть инвентарь, dough_recipes и продукты, которые являются долями рецептов теста.

Здесь он становится сложным/вытягивание волос начинается.

В каждом рецепте есть список ингредиентов с урожаем. *** В некоторых рецептах есть еще один рецепт в качестве ингредиента. Это тесто в тесте известно как предпочтительное и также известно как пул.

Один запрос предоставляет количество инвентаря, необходимого для любых заказов с предпочтительным вариантом, второй запрос обеспечивает текущий уровень запасов наряду с количеством инвентаря, необходимого для заказов (не включая какие-либо компоненты предпочтений).

Так как это сложно, я строю его, когда иду. Следующим шагом было бы как-то объединить эти два запроса.

Вот количество запасов, необходимое для всех заказов (не включая preferments):

SELECT SUM(dough_recipe_ingredient_pounds/dough_recipe_yield_pounds * weight *  
quantity_to_be_baked) as amount_needed_for_orders,id,title,inventory_pounds 
     FROM (
      SELECT 
      inventory.id, 
      inventory.title, 
      products.weight, 
      products.id AS product_id, 
      (orders_items.quantity - orders_items.quantity_baked) AS 
quantity_to_be_baked, 
       CASE inventory.units 
        WHEN 'kilograms' 
        THEN 2.20462 * inventory.quantity 
        WHEN 'pounds' 
        THEN 1 * inventory.quantity 
        WHEN 'ounces' 
        THEN 0.0625 * inventory.quantity 
        WHEN 'grams' 
        THEN 0.00220462 * inventory.quantity 
       END as inventory_pounds, 
       CASE dough_recipes.units 
        WHEN 'kilograms' 
        THEN 2.20462 * dough_recipes.amount 
        WHEN 'pounds' 
        THEN 1 * dough_recipes.amount 
        WHEN 'ounces' 
        THEN 0.0625 * dough_recipes.amount 
        WHEN 'grams' 
        THEN 0.00220462 * dough_recipes.amount 
       END AS dough_recipe_ingredient_pounds, 
      (orders_items.quantity - orders_items.quantity_baked) AS num_loaves_needed, 
       CASE doughs.units 
        WHEN 'kilograms' 
        THEN 2.20462 * doughs.yield 
        WHEN 'pounds' 
        THEN 1 * doughs.yield 
        WHEN 'ounces' 
        THEN 0.0625 * doughs.yield 
        WHEN 'grams' 
        THEN 0.00220462 * doughs.yield 
       END AS dough_recipe_yield_pounds 
      FROM inventory 
      LEFT JOIN dough_recipes ON inventory.id = dough_recipes.inventory_id 
      LEFT JOIN products ON dough_recipes.dough_id = products.dough_id 
      LEFT JOIN orders_items ON products.id = orders_items.product_id AND 
(orders_items.quantity - orders_items.quantity_baked) > 0 
      LEFT JOIN doughs ON doughs.id = products.dough_id 
     ) sq 
     GROUP BY id 

Вот количество запасов, необходимое для preferments всех орденов.

SELECT id,title, SUM(pre_ferment_recipe_ingredient_pounds/
pre_ferment_recipe_yield_pounds * weight * quantity_to_be_prepared) as 
amount_needed_for_orders 
     FROM (SELECT inventory.id, 
       inventory.title, 
       dough_pre_ferments.amount, 
       dough_pre_ferments.unit, 
       products.weight, 
       (order_preferments.quantity-order_preferments.quantity_prepared) as 
quantity_to_be_prepared, 
      CASE pre_ferment_recipes.units 
       WHEN 'kilograms' 
       THEN 2.20462 * pre_ferment_recipes.amount 
       WHEN 'pounds' 
       THEN 1 * pre_ferment_recipes.amount 
       WHEN 'ounces' 
       THEN 0.0625 * pre_ferment_recipes.amount 
       WHEN 'grams' 
       THEN 0.00220462 * pre_ferment_recipes.amount 
      END AS pre_ferment_recipe_ingredient_pounds, 

      CASE pre_ferments.units 
        WHEN 'kilograms' 
        THEN 2.20462 * pre_ferments.yield 
        WHEN 'pounds' 
        THEN 1 * pre_ferments.yield 
        WHEN 'ounces' 
        THEN 0.0625 * pre_ferments.yield 
        WHEN 'grams' 
        THEN 0.00220462 * pre_ferments.yield 
      END AS pre_ferment_recipe_yield_pounds 

      FROM inventory 
      LEFT JOIN pre_ferment_recipes ON pre_ferment_recipes.inventory_id = 
inventory.id 
      LEFT JOIN dough_pre_ferments ON dough_pre_ferments.pre_ferment_id = 
pre_ferment_recipes.pre_ferment_id 
      LEFT JOIN products ON products.dough_id = dough_pre_ferments.dough_id 
      LEFT JOIN pre_ferments ON pre_ferments.id = 
pre_ferment_recipes.pre_ferment_id 
      LEFT JOIN order_preferments ON order_preferments.preferment_id = 
pre_ferment_recipes.pre_ferment_id 
      ) sq 
      GROUP BY id 
+0

ну, просто глядя на количество вещей, которые вы делаете с этими вопросами ..попытка их комбинирования сильно повредила бы производительность. можете ли вы опубликовать схему? это очень помогло бы. –

+0

Производительность - это не проблема, ее управляет только один парень за раз. Вот ссылка на БД с некоторыми данными psuedo. http://forfrom.com/db.sql –

ответ

1

вот рабочее решение на ваш вопрос.

SELECT id, title, SUM(amount_needed_for_orders) 
FROM(
(SELECT id,title, SUM(dough_recipe_ingredient_pounds/dough_recipe_yield_pounds * weight *  
quantity_to_be_baked) as amount_needed_for_orders 
     FROM (
      SELECT 
      inventory.id, 
      inventory.title, 
      products.weight, 
      products.id AS product_id, 
      (orders_items.quantity - orders_items.quantity_baked) AS 
quantity_to_be_baked, 
       CASE inventory.units 
        WHEN 'kilograms' 
        THEN 2.20462 * inventory.quantity 
        WHEN 'pounds' 
        THEN 1 * inventory.quantity 
        WHEN 'ounces' 
        THEN 0.0625 * inventory.quantity 
        WHEN 'grams' 
        THEN 0.00220462 * inventory.quantity 
       END as inventory_pounds, 
       CASE dough_recipes.units 
        WHEN 'kilograms' 
        THEN 2.20462 * dough_recipes.amount 
        WHEN 'pounds' 
        THEN 1 * dough_recipes.amount 
        WHEN 'ounces' 
        THEN 0.0625 * dough_recipes.amount 
        WHEN 'grams' 
        THEN 0.00220462 * dough_recipes.amount 
       END AS dough_recipe_ingredient_pounds, 
      (orders_items.quantity - orders_items.quantity_baked) AS num_loaves_needed, 
       CASE doughs.units 
        WHEN 'kilograms' 
        THEN 2.20462 * doughs.yield 
        WHEN 'pounds' 
        THEN 1 * doughs.yield 
        WHEN 'ounces' 
        THEN 0.0625 * doughs.yield 
        WHEN 'grams' 
        THEN 0.00220462 * doughs.yield 
       END AS dough_recipe_yield_pounds 
      FROM inventory 
      LEFT JOIN dough_recipes ON inventory.id = dough_recipes.inventory_id 
      LEFT JOIN products ON dough_recipes.dough_id = products.dough_id 
      LEFT JOIN orders_items ON products.id = orders_items.product_id AND 
(orders_items.quantity - orders_items.quantity_baked) > 0 
      LEFT JOIN doughs ON doughs.id = products.dough_id 
     ) sq 
     GROUP BY id 
) 
UNION ALL 

(SELECT id,title, SUM(pre_ferment_recipe_ingredient_pounds/
pre_ferment_recipe_yield_pounds * weight * quantity_to_be_prepared) as 
amount_needed_for_orders 
     FROM (SELECT inventory.id, 
       inventory.title, 
       dough_pre_ferments.amount, 
       dough_pre_ferments.unit, 
       products.weight, 
       (order_preferments.quantity-order_preferments.quantity_prepared) as 
quantity_to_be_prepared, 
      CASE pre_ferment_recipes.units 
       WHEN 'kilograms' 
       THEN 2.20462 * pre_ferment_recipes.amount 
       WHEN 'pounds' 
       THEN 1 * pre_ferment_recipes.amount 
       WHEN 'ounces' 
       THEN 0.0625 * pre_ferment_recipes.amount 
       WHEN 'grams' 
       THEN 0.00220462 * pre_ferment_recipes.amount 
      END AS pre_ferment_recipe_ingredient_pounds, 

      CASE pre_ferments.units 
        WHEN 'kilograms' 
        THEN 2.20462 * pre_ferments.yield 
        WHEN 'pounds' 
        THEN 1 * pre_ferments.yield 
        WHEN 'ounces' 
        THEN 0.0625 * pre_ferments.yield 
        WHEN 'grams' 
        THEN 0.00220462 * pre_ferments.yield 
      END AS pre_ferment_recipe_yield_pounds 

      FROM inventory 
      LEFT JOIN pre_ferment_recipes ON pre_ferment_recipes.inventory_id = 
inventory.id 
      LEFT JOIN dough_pre_ferments ON dough_pre_ferments.pre_ferment_id = 
pre_ferment_recipes.pre_ferment_id 
      LEFT JOIN products ON products.dough_id = dough_pre_ferments.dough_id 
      LEFT JOIN pre_ferments ON pre_ferments.id = 
pre_ferment_recipes.pre_ferment_id 
      LEFT JOIN order_preferments ON order_preferments.preferment_id = 
pre_ferment_recipes.pre_ferment_id 
      ) sq 
      GROUP BY id 
) 
) as t 
GROUP BY id 

EDIT:

здесь рабочий раствор с соединениями.

SELECT 
    t.id, t.title, t.inventory_pounds, 
    t.amount_needed_for_orders + t1.amount_needed_for_orders 
FROM(
    SELECT 
     id,title, inventory_pounds, 
     SUM(dough_recipe_ingredient_pounds/dough_recipe_yield_pounds * weight * quantity_to_be_baked) AS amount_needed_for_orders 
     FROM (
      SELECT 
      inventory.id, 
      inventory.title, 
      products.weight, 
      products.id AS product_id, 
      (orders_items.quantity - orders_items.quantity_baked) AS quantity_to_be_baked, 
       CASE inventory.units 
        WHEN 'kilograms' 
        THEN 2.20462 * inventory.quantity 
        WHEN 'pounds' 
        THEN 1 * inventory.quantity 
        WHEN 'ounces' 
        THEN 0.0625 * inventory.quantity 
        WHEN 'grams' 
        THEN 0.00220462 * inventory.quantity 
       END AS inventory_pounds, 
       CASE dough_recipes.units 
        WHEN 'kilograms' 
        THEN 2.20462 * dough_recipes.amount 
        WHEN 'pounds' 
        THEN 1 * dough_recipes.amount 
        WHEN 'ounces' 
        THEN 0.0625 * dough_recipes.amount 
        WHEN 'grams' 
        THEN 0.00220462 * dough_recipes.amount 
       END AS dough_recipe_ingredient_pounds, 
      (orders_items.quantity - orders_items.quantity_baked) AS num_loaves_needed, 
       CASE doughs.units 
        WHEN 'kilograms' 
        THEN 2.20462 * doughs.yield 
        WHEN 'pounds' 
        THEN 1 * doughs.yield 
        WHEN 'ounces' 
        THEN 0.0625 * doughs.yield 
        WHEN 'grams' 
        THEN 0.00220462 * doughs.yield 
       END AS dough_recipe_yield_pounds 
      FROM inventory 
      LEFT JOIN dough_recipes ON inventory.id = dough_recipes.inventory_id 
      LEFT JOIN products ON dough_recipes.dough_id = products.dough_id 
      LEFT JOIN orders_items ON products.id = orders_items.product_id AND 
(orders_items.quantity - orders_items.quantity_baked) > 0 
      LEFT JOIN doughs ON doughs.id = products.dough_id 
     ) sq 
     GROUP BY id 
) AS t 
JOIN 
( SELECT 
     id,title, 
     SUM(pre_ferment_recipe_ingredient_pounds/pre_ferment_recipe_yield_pounds * weight * quantity_to_be_prepared) AS amount_needed_for_orders 
    FROM (SELECT inventory.id, 
       inventory.title, 
       dough_pre_ferments.amount, 
       dough_pre_ferments.unit, 
       products.weight, 
       (order_preferments.quantity-order_preferments.quantity_prepared) AS 
quantity_to_be_prepared, 
      CASE pre_ferment_recipes.units 
       WHEN 'kilograms' 
       THEN 2.20462 * pre_ferment_recipes.amount 
       WHEN 'pounds' 
       THEN 1 * pre_ferment_recipes.amount 
       WHEN 'ounces' 
       THEN 0.0625 * pre_ferment_recipes.amount 
       WHEN 'grams' 
       THEN 0.00220462 * pre_ferment_recipes.amount 
      END AS pre_ferment_recipe_ingredient_pounds, 

      CASE pre_ferments.units 
        WHEN 'kilograms' 
        THEN 2.20462 * pre_ferments.yield 
        WHEN 'pounds' 
        THEN 1 * pre_ferments.yield 
        WHEN 'ounces' 
        THEN 0.0625 * pre_ferments.yield 
        WHEN 'grams' 
        THEN 0.00220462 * pre_ferments.yield 
      END AS pre_ferment_recipe_yield_pounds 

      FROM inventory 
      LEFT JOIN pre_ferment_recipes ON pre_ferment_recipes.inventory_id = inventory.id 
      LEFT JOIN dough_pre_ferments ON dough_pre_ferments.pre_ferment_id = pre_ferment_recipes.pre_ferment_id 
      LEFT JOIN products ON products.dough_id = dough_pre_ferments.dough_id 
      LEFT JOIN pre_ferments ON pre_ferments.id = pre_ferment_recipes.pre_ferment_id 
      LEFT JOIN order_preferments ON order_preferments.preferment_id = pre_ferment_recipes.pre_ferment_id 
      ) sq 
      GROUP BY id 
) AS t1 ON t.id = t1.id 
GROUP BY id 
+0

Кто-нибудь думает, что можно комбинировать запросы без использования UNION? Подтвержденный, этот запрос работает. Однако, прежде чем я выберу этот зеленый флажок, я хочу убедиться, что это единственный способ. –

+0

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

+0

@ user2094495 Позвольте мне немного изучить его. Возможно, я смогу придумать быстрое решение. –

0

Так вы говорите, производительность не является проблемой, вы можете использовать UNION, и агрегатную функцию, чтобы получить сумму.

Во-первых, вам нужно будет изменить столбцы запросов, чтобы выполнить объединение. Вы должны иметь одинаковые столбцы в том же порядке. Поэтому я добавлю inventory_pounds ко второму запросу как 0, вы можете написать соответствующий SQL, чтобы получить его правильно. (Или вы можете оставить inventory_pounds из первого запроса, если это возможно).

SELECT id, title, inventory_pounds, SUM(dough_recipe_ingredient_pounds/dough_recipe_yield_pounds * weight *  
quantity_to_be_baked) as amount_needed_for_orders, 
     FROM (...) 
     GROUP BY id 

SELECT id, title, 0 as inventory_pounds, SUM(pre_ferment_recipe_ingredient_pounds/
pre_ferment_recipe_yield_pounds * weight * quantity_to_be_prepared) as 
amount_needed_for_orders 
     FROM (...) 
     GROUP BY id 

Затем вы можете выполнить UNION на двух запросов:

(SELECT id, title, inventory_pounds, SUM(dough_recipe_ingredient_pounds ...) 
UNION 
(SELECT id, title, 0 as inventory_pounds, SUM(pre_ferment_recipe_ingredient_pounds ...) 

Теперь это может содержать повторяющиеся id с. Итак, сделайте GROUP BY с SUM.

SELECT id, title, 
     SUM(inventory_punds) as sum_pounds, 
     SUM(amount_needed_for_orders) sum_amount_needed_for_orders 
FROM 
(SELECT id, title, inventory_pounds, SUM(dough_recipe_ingredient_pounds ...) 
UNION 
(SELECT id, title, 0 as inventory_pounds, SUM(pre_ferment_recipe_ingredient_pounds ...) 
GROUP BY id, title; 
+0

Если я не смогу найти способ объединить два запроса в один, я получу эту идею UNION. Спасибо за идею. –

Смежные вопросы