0

我有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)。

4

3 回答 3

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 条件中。

于 2013-05-31T07:26:18.730 回答
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
于 2013-05-31T07:28:58.833 回答
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
于 2013-05-31T07:29:26.490 回答