Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使用多个联接筛选多个值_Sql_Mysql_Join - Fatal编程技术网

Sql 如何使用多个联接筛选多个值

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) 因此,这里的基本思想是,单个产品可以有多个子产品(模型),单个子产品可以有多个特性(或等级库),并且子产品的单个特性可以有多个值 现在假设有一个产品有多个子产品,这些子产品有多

这是一个模糊的标题,如果你能想出更好的,请更正它

考虑以下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;值='螺栓'

其中
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',在第二次连接检查中检查“螺栓”。如果你的属性是动态的,那么你可能需要做一些其他的把戏。也只是出于好奇,为什么你在产品图片上有一个子选择,而你可以作为一个连接来做?再选择的计划应该效率更低。绝对令人惊讶,先生。你让我高兴极了!