使用嵌套子查询优化mysql查询

时间:2012-05-18 00:54:39

标签: mysql sql subquery

总而言之,我有一些稍微复杂的查询(请参阅下面的示例),并且需要将结果保存到表中,而不是每次都运行它们。我有大约6个月的MYSQL经验,所以我知道这足以让自己陷入困境。

背景:每个产品都有多个规则来确定定价,发货等.kitruleoptions表将每个规则连接到它将应用的下拉选项 - 因此,如果客户选择"添加可选X,&#34 ;有关X的规则得到应用。 optionsets表将每个ProductItemID连接到与之关联的下拉选项。因此,只有在该规则的一组下拉选项中找到所有产品项目的下拉选项时,规则才应适用于特定产品项目。换句话说,并非每次选择X时规则必然适用,而是每次在下拉列表A中选择X并且在下拉列表B中选择Y或Z时,它可以应用,但是如果W,则不是在下拉列表B中选择。

以下是一个示例查询,它可以获取单个ProductItemID的总价。

SELECT ProductItemID, SUM(RulePrice * ItemQuantity) AS Price FROM 
(SELECT RuleGroups, ProductItemGroups, RulePrice, ItemQuantity, productitems.ProductItemID
FROM kitrules
LEFT JOIN productitems ON productitems.ProductID = kitrules.ProductID
LEFT JOIN (SELECT RuleID, GROUP_CONCAT(OptionGroupID ORDER BY OptionGroupID) AS RuleGroups 
    FROM kitruleoptions
    WHERE OptionGroupID IN (SELECT OptionGroupID FROM optionsets WHERE ProductItemID = %s)
    GROUP BY RuleID) AS k ON k.RuleID = kitrules.RuleID
LEFT JOIN (SELECT ProductItemID, GROUP_CONCAT(OptionGroupID ORDER BY OptionGroupID) AS ProductItemGroups
    FROM optionsets
    GROUP BY ProductItemID) AS o ON o.ProductItemID = productitems.ProductItemID
WHERE productitems.ProductItemID = %s AND RuleGroups = ProductItemGroups) AS x
GROUP BY x.ProductItemID

目前,这个选择(或更确切地说,一个选择不仅仅是价格的更复杂的选择)进入INSERT INTO语句,如下所示:

INSERT INTO pricelists (ProductItemID, Price) 
SELECT [the query above] 
WHERE ProductItemID = %s

我正在尝试制定它,而不是像这样:

INSERT INTO pricelists (ProductItemID, Price)
SELECT [a new query that only requires ProductID]
WHERE ProductItemID IN (SELECT ProductItemID FROM productitems WHERE ProductID = %s)

...只需要输入ProductID即可立即更新整个产品。这样,我就不再需要遍历PHP数组来完成它了。 ProductID可以在kitrules表和productitems表中找到,所以我觉得应该有办法,但我似乎无法找到它。所以我的问题是,如何将查询重新表示为只需要ProductID?它甚至可能吗?有没有办法在没有GROUP_CONCAT的情况下直接比较一组选项集和一组kitruleoptions?另外,我如何用触发器设置它,它应该触发什么?我之前从未做过触发器。

编辑:这是我的SQL Fiddle,其中有一个关于表格应该如何结束的简单示例。我的想法是,我从一个设置开始,每个产品只有一个或多个项目,但由于需求的最新变化(yay),我不得不添加生成工具包或组合的能力多个不同的项目,但工具包本身就是项目。要求是套件的ItemCost是其包含的项目的总和' ItemCosts和套件的价格是其包含的规则的总和' RulePrices乘以ItemQuantity,其运输由其包含的项目的组合运输确定。发货信息,但除此之外,套件只是另一个项目。提示三周头痛和计数。

1 个答案:

答案 0 :(得分:1)

我最终弄明白了:

SELECT ProductItemID, SUM(RulePrice * ItemQuantity) AS TotalPrice FROM
(SELECT p.ProductItemID, k.RuleID, p_count, COUNT(k.RuleID) AS k_count,
RulePrice, ItemQuantity
FROM productitems
INNER JOIN optionsets o ON productitems.ProductItemID = o.ProductItemID
INNER JOIN (SELECT ProductItemID, COUNT(OptionGroupID) AS p_count 
        FROM optionsets
        GROUP BY ProductItemID) AS p ON p.ProductItemID = o.ProductItemID
LEFT JOIN kitruleoptions k ON k.OptionGroupID = o.OptionGroupID
LEFT JOIN kitrules ON k.RuleID = kitrules.RuleID
WHERE productitems.ProductID = %s
GROUP BY o.ProductItemID, k.RuleID
HAVING k_count = p_count) AS x
GROUP BY x.ProductItemID