2014-02-08 71 views
1

在MySQL中我有3个表名为“产品”,“PRODUCT_GROUP”和“PRODUCT_CATEGORY”MySQL查询加盟值

产品可以通过“PRODUCT_GROUP”表中彼此相关。

产品可以通过“product_category”表格显示在特定类别中。

我想要做的是从特定类别中检索所有产品,这些产品要么有价格,要么包含一个或多个有价格的子产品。

这里的表的一个示例:

product 
======= 
product_id  price 
1    10.00 
2    20.00 
3    0.00 
4    40.00 
5    50.00 
6    0.00 
7    0.00 
8    0.00 
9    0.00 
10    0.00 
11    1.99 

product_group 
============= 
product_id  child_product_id 
6    1 
6    2 
7    3 
7    4 
8    9 

product_category 
================ 
category_id  product_id 
1    5 
1    6 
1    7 
1    8 
1    10 
2    11 

这意味着产品1和2是产品的儿童6.产品3和4是产品的儿童7.产品9是产品8的子级。

产品5,6,7,8和10是在类别1

我要的是一个查询返回所有产品类别1中,要么有一个价格,或者包含具有一个或多个孩子一个价格。所以我期望得到产品5,6,7。尽管产品8和10都属于第1类,但我不想要这些产品,因为它们没有价格,并且不包含有价格的儿童。

我可以使用内部和左连接的组合来发布我迄今为止编写的查询,但我担心它完全错误。

谢谢你的期待。

*编辑*

我发现我原来的查询做的工作,我得到了数据在我的两个列混合起来的。这里是我的下面原始查询:

SELECT p.product_id 
    FROM product p 
    JOIN product_category c 
    ON c.product_id = p.product_id 
    AND c.category_id = 1 
    LEFT 
    JOIN product_group g 
    ON p.product_id = g.product_id 
    LEFT 
    JOIN product AS p2 
    ON p2.product_id = g.child_product_id 
    AND p2.price > 0 
WHERE p.price > 0 OR p2.product_id IS NOT NULL 
GROUP BY p.product_id 
+2

我会说继续并发布你写的查询。谁在乎它是否错误?这就是你来这里的原因,对吧? – Aaron

回答

1

我会做这样的事情:

SELECT p.product_id 
    FROM product p 
    JOIN product_category c 
    ON c.product_id = p.product_id 
    AND c.category_id = 1 
    LEFT 
    JOIN (SELECT g.product_id 
      FROM product_group g 
      JOIN product h 
      ON h.product_id = g.child_product_id 
      AND h.price > 0.00 
      GROUP BY g.product_id 
     ) r 
    ON r.product_id = p.product_id 
WHERE p.price > 0 
    OR r.product_id IS NOT NULL 

注:

联接到PRODUCT_CATEGORY得到我们的限制,该产品必须在类别1中。

内联视图(派生表别名为r)获取我们的列表“paren t“product_id,其具有有价格的child_product_id。

我们做了一个OUTER连接,所以我们仍然获得了类别1中的所有行,我们只是做一个匹配。

在WHERE子句中,我们过滤掉了行,并且只保留那些有价格的产品,或者与内嵌视图相匹配的行。

这只是一种方法,有几种方法可以获得等效的结果集。

这假定product_id在产品表中是唯一的。

这也假定(category_id,product_id)元组在product_category表中是唯一的,也就是说,不会有重复的,例如, (1,5),(1,5)。如果该假设无效,那么我们可能希望在查询末尾添加一个GROUP BY p.product_id,以获得一个清晰的列表。

此外,这只看直接的孩子;它并不期望看到孙子(孩子的孩子)是否有价格。

+0

您对product_id和元组唯一的假设都是正确的。我会稍后尝试查询,并告诉你它是否有效 - 谢谢 – MrCarrot

+0

@MrCarrot:你可以在内联视图中运行查询别名为r,以验证它是否返回一个正确的列表(product_id有一个子产品,有价格。)您也可以修改WHERE子句来检查产品价格,并对其进行修改,以便仅检查来自r的匹配行。 – spencer7593

+0

谢谢@ spencer7593,我将把你的标记为正确的答案。然而,我发现我的原始查询确实有效(我编辑了我的问题以包含它,并且我重命名了表别名以使其与您的相比) - 我导入后在列中混合了数据,因此我认为它是失败。我已经解释了你的查询,它有5个步骤。我的查询有4个步骤,但由于GROUP BY而使用文件夹。我不确定哪个效率最高,但我现在有几个工作选项。我很想听听你对两者进行比较的看法。谢谢! – MrCarrot