如何使用多个JOIN过滤多个值

时间:2010-12-17 01:05:12

标签: sql mysql join

这是一个模糊的标题,所以如果你能想到一个更好的标题,请纠正它。

考虑这4个表:

产品:id(int),name,msrp等......

子产品:id(int),product_id(int),name(varchar)

subproducts_properties :id(int),subproduct_id(int),property_id(int)

subproducts_properties_values :subproducts_properties_id(int),value(varchar)

所以这里的基本思想是单个产品可以有多个子产品(模型),单个子产品可以有多个属性(或规格),子产品的单个属性可以有多个值。

现在假设有一个产品有多个子产品,这些子产品具有多个具有多个值的属性。特别是,该产品的副产品具有以下特性:

  

属性1 - property_id:1; value ='。17 HMR';

     

属性2 - property_id:22; value ='Bolt';

其中property_id 1的名称为Caliberproperty_id 2的名称为Action(想想:枪支)。

用户有下拉框,可以根据唯一值选择多个过滤器集。因此,如果用户选择property_id=1 value='5.56 mm NATO'Caliber .17 HMR,他应该会看到我们的产品,但当他退回ActionBoltBolt,他应该看到没有产品,因为我们的产品与这两种过滤器都不匹配。

所以......鉴于此信息,我想撤回数据库中的所有产品(每行一个产品)并按多个属性值过滤。我目前的尝试是这样的:

Caliber

要关注的部分是5.56 mm NATO子句中的最后一个SELECT p.*, m.name as manufacturer_name, pt.name as product_type_name, COUNT(DISTINCT com.id) AS num_reviews, ROUND(AVG(com.rating), 1) as rating, pi.image_thumb FROM products p LEFT JOIN manufacturers m ON p.manufacturer_id=m.id LEFT JOIN product_types pt ON p.product_type_id=pt.id LEFT JOIN comments com ON p.id=com.object_id AND com.object_group = 'com_products' AND com.level=0 LEFT JOIN ( SELECT product_id, thumb_path as image_thumb FROM products_images pi ORDER BY ordering ASC ) AS pi ON p.id=pi.product_id LEFT JOIN subproducts sp ON p.id=sp.product_id LEFT JOIN subproducts_properties spp ON sp.id=spp.subproduct_id LEFT JOIN subproducts_properties_values sppv ON spp.id=sppv.sp_id WHERE p.deleted != 1 AND p.published=1 AND ( IF(spp.property_id=1, IF(sppv.value='5.56 mm NATO',1,0), 0) = 1 OR IF(spp.property_id=22, IF(sppv.value='Bolt',1,0), 0) = 1 ) GROUP BY p.id ORDER BY p.created DESC LIMIT 0, 12 ,我试图让过滤器继续运行。另请注意,我有一个AND,以便能够在其他表上执行聚合函数。这个特定的查询会因为最后WHERE内的GROUP BY而撤回我们的产品,但我想设置它以便在这种情况下不会将其拉回来,但会将其拉回来如果代替OR,则AND(这是我们子产品的值)。

我已尝试在其中放置AND,但它不会返回任何内容,因为每个值在sppv表中都有自己的行。

请帮忙!我完全迷失在这里做什么。

提前致谢!

1 个答案:

答案 0 :(得分:1)

尝试拥有 - 计数 - 如果不是在哪里:

WHERE p.deleted != 1 AND p.published=1 
GROUP BY p.id 
HAVING COUNT(IF(spp.property_id = 1 AND sppv.value='5.56 mm NATO',1,NULL)) > 0 
       AND COUNT(IF(spp.property_id=22 AND sppv.value='Bolt',1,NULL)) > 0
ORDER BY p.created DESC