MySQL:获取列出所有属性的产品

时间:2013-06-28 10:04:58

标签: php mysql

我遇到了一些问题,让我的查询正常运行。

我有三张牌桌:productsproduct_attributesattributes 关系很明显(产品可以有多个属性)

products
---------
id

product_attributes
------------------
product_id
attribute_id

attributes
----------
id
name

我想要实现的是获得具有给定属性列表的产品,但是省略那些仅具有所需属性的部分列表的产品。
例如,拥有这些产品和属性:

  • 鞋1 [蓝色,男孩]
  • 鞋2 [蓝色,女孩]
  • 鞋3 [红,男孩]
  • 鞋4 [红,女孩]

询问带有[blue,boy]的产品的查询只会检索Shoe 1 询问带有[蓝色]的产品的查询不会返回任何内容。

从现在开始我正在使用此查询:

SELECT p.*, pa.attribute_id
FROM products AS p 
LEFT JOIN product_attributes AS pa ON(pa.product_id=p.id)
WHERE 
pa.attribute_id IN(' . implode(',', $attr_ids) . ')
GROUP BY p.id
HAVING count(pa.attribute_id)=' . count($attr_ids)

仅在给出属性时失败,因为它将返回具有该属性的任何产品。

2 个答案:

答案 0 :(得分:2)

-- PHP (or any other languaje) parts are hardcoded here!!!!

SELECT p.*, hma.howmuchattr
-- howmuchattr is needed by HAVING clause, 
-- you can omit elsewhere (by surrounding SELECT or by programming languaje)

FROM products AS p 
LEFT JOIN product_attributes AS pa ON pa.product_id = p.id 
LEFT JOIN (
    SELECT product_id, count(*) as howmuchattr
    FROM product_attributes 
    GROUP BY product_id
) as hma on p.id = hma.product_id

WHERE 
pa.attribute_id IN 
(1,3)                    -- this cames from PHP (or any other languaje). Can be (1) for the other case
GROUP BY p.id
HAVING count(*) = howmuchattr;

在此处查看sqlfiddle 另见this answer

答案 1 :(得分:0)

除了任何其他问题,此查询...

  SELECT p.*
       , pa.attribute_id
    FROM products p 
    LEFT 
-- OUTER (this keyword is optional in MySQL)
    JOIN product_attributes pa 
      ON pa.product_id = p.id
   WHERE pa.attribute_id IN('$attr_ids')
   GROUP 
      BY p.id
  HAVING COUNT(*) = $cnt;

......在逻辑上与......相同。

  SELECT p.*
       , pa.attribute_id
    FROM products p 
-- INNER (this keyword is also optional in MySQL)
    JOIN product_attributes pa 
      ON pa.product_id = p.id
   WHERE pa.attribute_id IN('$attr_ids')
   GROUP 
      BY p.id
  HAVING COUNT(pa.attribute_id) = $cnt;

为了保持OUTER JOIN的实用性,请考虑重写如下......

  SELECT p.*
       , pa.attribute_id
    FROM products p 
    LEFT 
    JOIN product_attributes pa 
      ON pa.product_id = p.id
     AND pa.attribute_id IN('$attr_ids')
   GROUP 
      BY p.id
  HAVING COUNT(pa.attribute_id) = $cnt;