我需要选择具有特定value_id的产品ID。
表products
:
| product_id | product_name | category_id | active |
| 125 | notebook1 | 3 | 1 |
| 236 | notebook2 | 3 | 1 |
表filters
:
| product_id | value_id | value_name |
| 125 | 35 | 15" display|
| 125 | 36 | 8GB RAM |
| 236 | 35 | 15" display|
如果我想通过一个value_id选择产品ID,则此选择正常:
SELECT DISTINCT p.product_id FROM products p
LEFT JOIN filters f ON (p.product_id=f.product_id)
WHERE p.active=1 AND p.category_id=3 AND f.value_id=36;
但是当我在网上查看更多过滤器时,我需要选择更多值,问题是当我使用时:
SELECT DISTINCT p.product_id FROM products p
LEFT JOIN filters f ON (p.product_id=f.product_id)
WHERE p.active=1 AND p.category_id=3 AND f.value_id IN(35,36);
它给我的产品有15“显示 OR 8GB RAM,我需要的产品有15”显示 AND 8GB RAM。感谢。
答案 0 :(得分:6)
我假设您提到Web后,您正在使用程序语言来生成查询。我还假设您无法控制表中数据的结构,因此我们必须有一个选项,在给定的表结构的情况下可以使用。
以下选项有效,但如果您正在处理大量传入的选项,则会变得草率。
SELECT
DISTINCT p.product_id
FROM
products p
JOIN filters f1
ON p.product_id=f1.product_id
and f1.value_id = 35
JOIN filters f2
ON p.product_id=f2.product_id
and f2.value_id = 36
WHERE
p.active=1
AND p.category_id=3
;
如果您在逗号分隔列表中获取过滤器值id并希望以这种方式使用它(提示您的IN语句),则可以采用此方法。我假设您知道传入的过滤器值的总数。在您的示例中,您有2个,因此查询会这样。
SELECT
p.product_id
FROM
products p
JOIN filters f
ON p.product_id=f.product_id
AND p.active=1
AND p.category_id=3
AND f.value_id IN(35,36)
GROUP BY
p.product_id
HAVING
COUNT(p.product_id) = 2
同样在join条件而不是where子句中加入将有助于加快查询速度,因为from子句是在where子句之前计算的。
答案 1 :(得分:0)
尝试一下:
SELECT product_id FROM filters
WHERE value_id IN (35, 36)
GROUP BY product_id
HAVING COUNT(DISTINCT value_id) = 2
这将输出125
。
请注意,如果给定的product_id
不能多次使用value_id
,那么您可以删除DISTINCT
关键字。
小提琴here。
基于您上一个查询的完整查询是:
SELECT f.product_id FROM filters f
JOIN products p ON f.product_id = p.product_id
WHERE f.value_id IN (35, 36) AND p.active = 1 AND p.category_id = 3
GROUP BY f.product_id
HAVING COUNT(f.value_id) = 2
答案 2 :(得分:0)
如果您需要15“显示器和8GB RAM的输出。
SELECT product_id FROM products
WHERE product_id IN(SELECT DISTINCT product_id from filters WHERE value_id IN(35,35) GROUP BY value_name)