Sql 如何使用多个联接筛选多个值
这是一个模糊的标题,如果你能想出更好的,请更正它 考虑以下4个表: 产品:id(int)、名称、msrp等 子产品:标识(int)、产品标识(int)、名称(varchar) 子管道\u属性:id(int)、子管道\u id(int)、属性\u id(int) 子产品属性值:子产品属性id(int)、值(varchar) 因此,这里的基本思想是,单个产品可以有多个子产品(模型),单个子产品可以有多个特性(或等级库),并且子产品的单个特性可以有多个值 现在假设有一个产品有多个子产品,这些子产品有多个属性,这些属性有多个值。特别是,此产品的子产品具有以下属性: 属性1-属性id:1;值='.17 HMR' 物业2-物业id:22;值='螺栓' 其中Sql 如何使用多个联接筛选多个值,sql,mysql,join,Sql,Mysql,Join,这是一个模糊的标题,如果你能想出更好的,请更正它 考虑以下4个表: 产品:id(int)、名称、msrp等 子产品:标识(int)、产品标识(int)、名称(varchar) 子管道\u属性:id(int)、子管道\u id(int)、属性\u id(int) 子产品属性值:子产品属性id(int)、值(varchar) 因此,这里的基本思想是,单个产品可以有多个子产品(模型),单个子产品可以有多个特性(或等级库),并且子产品的单个特性可以有多个值 现在假设有一个产品有多个子产品,这些子产品有多
property\u id 1
有一个名称calible
,property\u id 2
有一个名称Action
(想想枪)
此产品没有的是包含属性的子产品,该属性的属性id=1
和值='5.56 mm NATO'
用户有下拉框,可以根据唯一值选择多个过滤器集。因此,如果用户选择口径为.17 HMR
和动作螺栓,他应该期望看到我们的产品,但是当他向后拉螺栓和口径为,比如说5.56 mm北约时,他应该看不到任何产品,因为我们的产品与这两个过滤器都不匹配
因此…根据这些信息,我想撤回数据库中的所有产品(每行一个产品),并按多个属性值进行筛选。我目前的尝试是这样的:
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
要重点关注的部分是WHERE
子句中的最后一个和
,我试图在其中启动过滤器。还要注意,我有一个分组依据
,以便能够在其他表上执行聚合函数。由于最后一个和中的或,此特定查询将撤回我们的产品,但我想对其进行设置,使其在这种情况下不会撤回,但如果存在sppv.value='5.56 mm NATO'
而不是sppv.value='.17 HMR'
(这是我们子产品的值),则会撤回
我尝试将AND放入其中,但它没有返回任何内容,因为每个值在sppv表中都有自己的行
请帮忙!我完全不知道在这里该做什么
提前谢谢 尝试使用have-Count-If,而不是where:
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
EAV就像regexps:在你决定要用EAV解决你的问题后,你有两个问题。@zerkms我在这背后的理论上有点新手。@treeface:我的意思是,EAV(存储数据的方式)看起来非常灵活和漂亮,但是当你需要编写一些或多或少复杂的查询时,你会感到痛苦。注意最后一句话:“我希望你觉得这本指南很有用,并且不鼓励你使用EAV设计。”我有点困惑你在问什么,所以如果我说的是弱智的话,请原谅我。我猜如果你的枪是“5.56毫米北约”并且是“螺栓”(同时具有这两种属性),你会希望返回一行吗?就像你说的,如果你把OR改成an,你就没有行了。这是因为一行不能有2个值。您可以连接到属性表两次。在第一次连接检查中,检查prop=1值='5.56 mm NATO',在第二次连接检查中检查“螺栓”。如果你的属性是动态的,那么你可能需要做一些其他的把戏。也只是出于好奇,为什么你在产品图片上有一个子选择,而你可以作为一个连接来做?再选择的计划应该效率更低。绝对令人惊讶,先生。你让我高兴极了!