MySQL查询过滤结果

问题描述 投票:2回答:4

下面是我的数据表,

1)产品

id    name    
------------
1     abc
2     def
3     xyz

2)product_attribute

id    product_id  attribute_id  attribute_value_id    
--------------------------------------------------
1     1           1             1
2     1           1             2
3     1           2             4
4     2           1             3
5     2           2             5
6     3           1             1
7     1           3             6

3)属性

id    name
---------------
1     color        
2     size
3     width

4)attribute_value

id    name
--------------
1     Red
2     Blue
3     Black
4     2.5
5     3.5
6     5

当找到颜色=红色的产品时,获得产品'abc'和'xyz。

SELECT * 
FROM product AS p 
INNER JOIN product_attribute AS pa ON pa.p_id = p.id 
WHERE (pa.attribute_id = 1 AND pa.attribute_value_id IN(1)) 
GROUP BY p.id

当找到颜色=红色且尺寸= 2.5的产品时,返回零结果。

SELECT * 
FROM product AS p 
INNER JOIN product_attribute AS pa ON pa.p_id = p.id 
WHERE ((pa.attribute_id = 1 AND pa.attribute_value_id IN(1)) 
  AND (pa.attribute_id = 2 AND pa.attribute_value_id IN(4))) 
GROUP BY p.id

如何获得颜色=红色和尺寸= 2.5的产品?

mysql sql
4个回答
2
投票

以下是使用连接获取匹配所有这些属性和值的产品的两种方法

使用count()

SELECT p.id,p.name  
FROM product p 
INNER JOIN product_attribute pa ON pa.product_id = p.id 
INNER JOIN attribute a ON a.id = pa.attribute_id
INNER JOIN attribute_value av ON av.id = pa.attribute_value_id
WHERE a.name IN('color','size')
AND av.name IN('red','2.5')
GROUP BY p.id,p.name
HAVING COUNT(DISTINCT a.id) = 2 
AND COUNT(DISTINCT av.id) = 2

通过使用sum()

SELECT p.id,p.name 
FROM product p 
INNER JOIN product_attribute pa ON pa.product_id = p.id 
INNER JOIN attribute a ON a.id = pa.attribute_id
INNER JOIN attribute_value av ON av.id = pa.attribute_value_id
GROUP BY p.id,p.name 
HAVING SUM(a.name = 'color' AND av.name = 'red') > 0
AND SUM(a.name = 'size' AND av.name = '2.5') > 0

DEMO


1
投票

终于得到了解决方案

使用Count()

SELECT p.id,p.name 
FROM product p 
INNER JOIN product_attribute pa ON pa.product_id = p.id 
where (
    (pa.attribute_id = 1 AND pa.attribute_value_id IN(1)) 
    OR (pa.attribute_id = 2 AND pa.attribute_value_id IN(4))
)GROUP BY p.id 
HAVING COUNT(p.id) = 2

您只需要添加过滤器的计数(如颜色,大小,宽度等)。

恩。如果你添加额外的过滤器宽度= 5,那么你可以添加COUNT(p.id)= 3。


0
投票

如果您的表不大,您可以使用exists

    SELECT * FROM product AS p 
            WHERE exists(select * from product_attribute AS pa where pa.p_id = p.id and pa.attribute_id = 1 AND pa.attribute_value_id = 1)  // color = red
                and exists(select * from product_attribute AS pa where pa.p_id = p.id and pa.attribute_id = 2 AND pa.attribute_value_id = 4) // size = 2.5

你也可以使用join,但它更复杂

SELECT * FROM product AS p 
        INNER JOIN product_attribute AS pa1 ON pa1.p_id = p.id and pa1.attribute_id = 1 AND pa1.attribute_value_id = 1   // color = red
        INNER JOIN product_attribute AS pa2 ON pa2.p_id = p.id and pa2.attribute_id = 2 AND pa2.attribute_value_id = 4  // size = 2.5

0
投票

如果你真的想使用像color = 'Red' and size = 2.5这样的条件我可以建议使用带有像这样的数据透视的查询:

select *
from (
    select p.id, p.name
        , max(case when a.name = 'color' then av.name end) color
        , max(case when a.name = 'size' then cast(av.name as decimal(12,2)) end) size
    from product_attribute pa
    left join product p on pa.product_id = p.id
    left join attribute a on pa.attribute_id = a.id
    left join attribute_value av on pa.attribute_value_id = av.id
    group by p.id, p.name ) t
where
    t.color = 'Red' and t.size = 2.5;

MySQL Fiddle Demo

© www.soinside.com 2019 - 2024. All rights reserved.