MySQL查询过滤结果

时间:2018-01-02 04:44:16

标签: mysql sql

Bellow是我的数据表,

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的产品?

4 个答案:

答案 0 :(得分: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 :(得分: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。

答案 2 :(得分: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

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

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

答案 3 :(得分: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