mysql—我想进行sql查询,以获得在单独表中具有属性的不同产品数据

j0pj023g  于 2021-06-25  发布在  Mysql
关注(0)|答案(2)|浏览(244)

我有:
产品(id、标题)
[1,'旧车'],[2,'新车'],[3,'未来汽车'])
属性(id、名称)
[1,'品牌'],[2,'型号'],[3,'颜色']
属性\值(属性\ id、产品\ id、值)
[1,1,'丰田'],[1,2,'本田'],[1,3,'福特'],[1,3,'红色'],[2,3,'白色'],[3,3,'红色']
我试着询问:

select p.*, a.name as attribute_name, av.value as attribute_value from attributes as a 
join attribute_values as av on a.id=av.attribute_id
join products as p on av.product_id=p.id
where
((a.name='brand' and av.value='toyota') or (a.name='color' and av.value='red'))

它给出与or查询条件匹配的每一行。
如:
[id:1,标题:'旧车',属性名称:'品牌',属性值:'丰田']
[id:1,标题:'old car',属性名称:'color',属性值:'red']
[id:3,标题:'future car',属性名称:'color',属性值:'red']
在这里,结果是:“旧车”和“未来车”,但我需要的是“旧车”而不是“未来车”。
这可以通过单个查询完成吗?

2izufjch

2izufjch1#

假设这是正确的,我已将属性值表中的记录更改如下:

attribute_id  |   product_id   |   value
------------------------------------------
1         |       1        |   toyota
1         |       2        |   honda
1         |       3        |   ford
3         |       1        |   red
3         |       2        |   white
3         |       3        |   red

我修改了你的查询如下:

select p.*, a.name as attribute_name, av.value as attribute_value from attributes as a 
    join attribute_values as av on a.id=av.attribute_id
    join products as p on av.product_id=p.id
    where
        (
            if(a.name='brand',av.value='toyota',0) 
      or if(a.name='color',av.value='red',0)
     ) 
GROUP BY p.id HAVING COUNT(av.attribute_id) =2

这里的“2”应该是动态的,取决于你过滤的属性的数量。因为在您的示例中,您使用了2个属性进行过滤,所以我提到了2个属性
小提琴出现在:http://sqlfiddle.com/#!9/b6ff9/2号

mgdq6dx1

mgdq6dx12#

您可以尝试此查询。当记录与一个条件匹配时,原始查询将输出一行。从结果中,我们检查相同的 product id 结果中是否有2条记录。如果是,意味着2个标准(品牌= Toyota &颜色= red )匹配相同的 product .

SELECT id as product_id, count(attribute_name) as attribute_count FROM
(
    select 
        p.*, 
        a.name as attribute_name, 
        av.value as attribute_value

    from products as p 
        join attribute_values as av
            on p.id = av.product_id
        join attributes as a 
            on a.id = av.attribute_id

    where
        (a.name='brand' and av.value='toyota')
        or (a.name='color' and av.value='red')

) a

GROUP BY a.id
HAVING (attribute_count = 2);

用于测试的sql fiddle链接:http://sqlfiddle.com/#!9/ab857a/2号
编辑:
另一方面,你也可以试试这个 second approach . 首先我们分开做两个 subselect 得到符合两个标准的产品。然后我们 JOIN 子项一起选择以获得符合这两个条件的产品:

SELECT
    a.*,
    b.attribute_2,
    b.value_2

FROM
(
    SELECT 
        p.*, 
        a.name as attribute_1, 
        av.value as value_1
    FROM
        products as p
        JOIN attribute_values as av 
            ON av.product_id = p.id
        JOIN attributes as a
            ON a.id = av.attribute_id
    WHERE
        a.name = 'brand'
        and av.value = 'toyota'
) a

JOIN

(
    SELECT 
        p.*, 
        a.name as attribute_2, 
        av.value as value_2
    FROM
        products as p
        JOIN attribute_values as av 
            ON av.product_id = p.id
        JOIN attributes as a
            ON a.id = av.attribute_id
    WHERE
        a.name = 'color'
        and av.value = 'red'
) b

ON a.id = b.id

sql fiddle代码示例:http://sqlfiddle.com/#!9/8b836d/1号

相关问题