1

我在让这个查询按预期工作时遇到了一些问题。

我有三个表productsproduct_attributesattributes
关系很明显(一个产品可以有多个属性)

products
---------
id

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

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

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

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

使用 [blue,boy] 查询那些产品的查询只会检索Shoe 1.
询问带有 [blue] 的那些产品的查询不会返回任何内容。

从现在开始我一直在使用这个查询:

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)

当只给出一个属性时,这会失败,因为它将返回具有该属性的任何产品。

4

2 回答 2

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
也看到这个答案

于 2013-06-28T13:34:04.597 回答
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;
于 2013-06-28T13:31:00.477 回答