1

我正在尝试寻找具有特定规格的产品。由于规格的复杂组合,我有另一个表是:m 与另一个表的关系。

product
id | other data ...
---+---------------
1  | bike
2  | bus
3  | car

product_spec
product_id | spec_id
-----------+---------------
1          | 1
1          | 2
1          | 3
2          | 1
2          | 3
2          | 4
3          | 2
3          | 4

现在我需要找到具有特定规格的产品。如果我有一个产品必须具备的规格列表,这会很好地工作:

SELECT p.id FROM product p, product_spec s
WHERE p.id = s.product_id AND s.spec_id IN (1, 2, 3)
GROUP BY p.id HAVING COUNT(p.id) = 3

(其中 3 是产品必须具有的规格数量)给出产品 1

SELECT p.id FROM product p, product_spec s
WHERE p.id = s.product_id AND s.spec_id IN (1, 3)
GROUP BY p.id HAVING COUNT(p.id) = 2

给出产品 1 和 2。到目前为止一切顺利。现在麻烦来了:

如果我想获得所有具有规格 1具有规格 2 或 4 的产品怎么办?

SELECT p.id FROM product p, product_spec s
WHERE p.id = s.product_id AND
    (s.spec_id = 1 OR s.spec_id IN (2, 4))
GROUP BY p.id HAVING COUNT(p.id) = 2

(显然)返回产品 1 和 3,但错误地返回 3,因为它确实同时具有规范 2 和 4,但没有 1。

我正在考虑提供不同的规范子句值(如规范组 1 = 1、规范组 2 = 2(规范组 3 = 4 等)),将它们加起来并使用HAVING SUM(extra_field) = 3,但我没有成功。

那么,如何进行这样的查询呢?我是否必须求助于多个查询(如果,最好的方法是什么)?

我正在使用 MySQL,但我认为问题不限于单个系统。

以下是重新创建这些测试表的语句:

CREATE TABLE product (
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  title varchar(20) NOT NULL,
  PRIMARY KEY (id)
);
INSERT INTO product (id, title) VALUES (1, 'bike'), (2, 'bus'), (3, 'car');
CREATE TABLE product_spec (
  product_id int(10) unsigned NOT NULL,
  spec_id int(10) unsigned NOT NULL,
  PRIMARY KEY (product_id,spec_id)
);
INSERT INTO product_spec (product_id, spec_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 2), (3, 4);
4

1 回答 1

1

您可以使用 SUM+CASE 计算各个“类别”的总和,并使用组合的 HAVING 查询:

SELECT p.id 
FROM 
  product p, 
  product_spec s
WHERE p.id = s.product_id 
GROUP BY p.id 
HAVING 
  SUM(case when s.spec_id = 1 then 1 else 0 end) > 0 and 
  SUM(case when s.spec_id in (2,4) then 1 else 0 end) > 0 
于 2013-04-23T11:41:59.050 回答