MySQL通过过滤器选择产品

时间:2013-11-22 02:17:34

标签: php mysql

我需要选择具有特定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。感谢。

3 个答案:

答案 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个,因此查询会这样。

组计数等于带有IN语句的过滤器

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)

SQL FIDDLE DEMO