我正在尝试查找具有特定规格的产品。由于规范的复杂组合,我有另一个表与另一个表的n: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。
我在考虑给出不同的spec子句值(比如规范组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);
答案 0 :(得分: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