加入条件困难的地方

时间:2013-05-31 07:19:49

标签: mysql sql join filter

我有product表和product_attributes表。我希望过滤产品具有必要的属性,这是我的sql:

SELECT * FROM product p 
INNER JOIN product_attributes p2 ON p.id = p2.product_id
WHERE p2.attribute_id IN (637, 638, 629))

但是,即使产品只有一个属性(例如637),它也能为我提供所有产品。但我需要具有所有给定属性的产品(637,638,629)。

3 个答案:

答案 0 :(得分:1)

有一种相当标准的方法:

select * from product
where id in (
    SELECT id
    FROM product p 
    JOIN product_attributes p2 ON p.id = p2.product_id
      AND p2.attribute_id IN (637, 638, 629)
    GROUP BY id
    HAVING COUNT(distinct attribute_id) = 3) 

HAVING子句确保有3个不同的属性id(即它们都被找到)。

这可以表示为直接连接(而不是ID IN(...)),但它更容易阅读,并且应该像这样执行。

稍微感兴趣的可能是将属性id条件移动到JOIN的ON条件中。

答案 1 :(得分:1)

这是“set-within-sets”子查询的示例。我喜欢用聚合和having子句来解决这些问题,因为这是最灵活的解决方案:

SELECT p.*
FROM product p join
     product_attributes pa
     on p.id = pa.product_id
group by p.id
having sum(pa.attribute_id = 637) > 0 and
       sum(pa.attribute_id = 638) > 0 and
       sum(pa.attribute_id = 629) > 0

另一个having子句是:

having count(distinct case when pa.attribute_id IN (637, 638, 629)
                           then pa.attribute_id
                      end) = 3

答案 2 :(得分:0)

您可以使用以下查询:

SELECT * FROM product p 
INNER JOIN product_attributes p21 
        ON p.id = p21.product_id and p21.attribute_id = 637
INNER JOIN product_attributes p22 
        ON p.id = p22.product_id and p22.attribute_id = 638
INNER JOIN product_attributes p23 
        ON p.id = p23.product_id and p23.attribute_id = 629