是否可以组合这些复杂的MYSQL查询?

时间:2014-08-01 04:13:01

标签: mysql

我有两个查询,都提供inventory.id,inventory.title和订单所需的金额。

我想要的是将它们组合在一起,以便将amount_needed_for_orders列的结果汇总在一起。

以下是对正在发生的事情的快速总结。我正在研究面包店库存管理计划。面包师有库存,面团食谱和面团配方的部分产品。

这是复杂/拔毛开始的地方。

每个配方都有成分列表,产量很高。 ***有些食谱中含有另一种食谱作为配料。面团中的这种面团被称为优选,也被称为池。

一个查询提供任意订单所需的库存量,第二个查询提供当前库存水平以及订单所需的库存量(不包括任何优惠成分)。

由于它很复杂,我正在建造它。下一步是以某种方式组合这两个查询。

以下是所有订单所需的库存量(不包括优惠):

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

以下是所有订单所需的广告资源量。

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

2 个答案:

答案 0 :(得分: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

修改

这是一个带连接的工作解决方案。

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

答案 1 :(得分: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;