修改MySQL IN以使其独占

时间:2014-05-12 16:31:13

标签: mysql opencart

我有以下MySQL查询。在my shop上使用此查询可在客户使用过滤缩小结果后检索产品。

我想修改此查询,以便只返回符合所有过滤条件的产品,现在它返回满足至少一个所选条件的任何产品。

对此负责的一行是在查询结束时:AND pf.filter_id IN (7,3,40)

是否可以修改此查询以实现我想要的行为?

到目前为止我尝试过的(不起作用):

我改变了

AND pf.filter_id IN (7,3,40)

AND pf.filter_id = 7 AND AND pf.filter_id = 3 AND AND pf.filter_id = 40

SELECT p.product_id,

  (SELECT AVG(rating) AS total
   FROM review r1
   WHERE r1.product_id = p.product_id
     AND r1.status = '1'
   GROUP BY r1.product_id) AS rating,

  (SELECT price
   FROM product_discount pd2
   WHERE pd2.product_id = p.product_id
     AND pd2.customer_group_id = '1'
     AND pd2.quantity = '1'
     AND ((pd2.date_start = '0000-00-00'
           OR pd2.date_start < NOW())
          AND (pd2.date_end = '0000-00-00'
               OR pd2.date_end > NOW()))
   ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount,

  (SELECT price
   FROM product_special ps
   WHERE ps.product_id = p.product_id
     AND ps.customer_group_id = '1'
     AND ((ps.date_start = '0000-00-00'
           OR ps.date_start < NOW())
          AND (ps.date_end = '0000-00-00'
               OR ps.date_end > NOW()))
   ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special
FROM product_to_category p2c
LEFT JOIN product_filter pf ON (p2c.product_id = pf.product_id)
LEFT JOIN product p ON (pf.product_id = p.product_id)
LEFT JOIN product_description pd ON (p.product_id = pd.product_id)
LEFT JOIN product_to_store p2s ON (p.product_id = p2s.product_id)
WHERE pd.language_id = '1'
  AND p.status = '1'
  AND p.date_available <= NOW()
  AND p2s.store_id = '0'
  AND p2c.category_id = '124'
  AND pf.filter_id IN (7,3,40)
GROUP BY p.product_id
ORDER BY p.sort_order ASC,
         LCASE(pd.name) ASC LIMIT 0,1

product_filter表中包含多个过滤器的示例产品:

product_id filter_id
753        6
753        7
753        44
753        47

SELECT filter_id, count(*) FROM product_filter GROUP BY filter_id(样本)的结果

filter_id count(*)
1         146
2         644
3         421
4         171
5         90
6         46
7         80
8         82

3 个答案:

答案 0 :(得分:1)

如果您需要对AND子句中的值执行IN()操作,这就是诀窍

SELECT
.... your select expression here 
FROM product_to_category p2c
LEFT JOIN product_filter pf ON (p2c.product_id = pf.product_id)
LEFT JOIN product p ON (pf.product_id = p.product_id)
LEFT JOIN product_description pd ON (p.product_id = pd.product_id)
LEFT JOIN product_to_store p2s ON (p.product_id = p2s.product_id)
WHERE pd.language_id = '1'
  AND p.status = '1'
  AND p.date_available <= NOW()
  AND p2s.store_id = '0'
  AND p2c.category_id = '124'
  AND pf.filter_id IN (7,3,40)
GROUP BY p.product_id
HAVING COUNT(DISTINCT pf.filter_id) >=3
ORDER BY p.sort_order ASC,
         LCASE(pd.name) ASC LIMIT 0,1

使用HAVING COUNT(DISTINCT pf.filter_id) >=3将满足过滤器7,3,40和更多过滤器的条件,但使用这3个过滤器,如果结果只有3个过滤器,甚至其他过滤器,那么您可以更改你的条件是HAVING COUNT(DISTINCT pf.filter_id) =3

答案 1 :(得分:0)

这是一些人称之为“集内查询集”的例子。 你需要做

SELECT product_id, count(*) 
FROM yourResults 
GROUP BY product_id
HAVING count(*) = 3

其中yourResults是您发布的查询的结果表的别名(使用filter_id IN

通过这种方式,您将获得所有产品ID,其中一行filter_id为3,一行为7,一行为40

答案 2 :(得分:-1)

执行您要求的最简单的方法是根本不使用IN,而是使用多个内连接:

JOIN product_filter pf1 ON pf1.product_id = p2c.productid AND pf1.filter_id = 7
JOIN product_filter pf2 ON pf2.product_id = p2c.productid AND pf2.filter_id = 3
JOIN product_filter pf3 ON pf3.product_id = p2c.productid AND pf3.filter_id = 40

此方法确保只返回满足每个谓词的集合。