MySQL find_in_set用于包含集

时间:2015-12-27 07:29:00

标签: mysql

我有以下SQL查询,在这种情况下搜索产品:

SELECT     sql_cache distinct p.products_id
FROM       products p 
INNER JOIN filter_association_products fap 
ON         p.products_id =fap.products_id 
WHERE      p.products_status = '1' 
AND        date_sub(curdate(),interval 3000 day) <= p.products_date_added 
AND        find_in_set(fap.filter_id,'130,128') 
ORDER BY   p.products_date_added DESC

目前我得到的结果是所有产品都有fap.filter_id 128和fap.filter_id 130,但我希望它只列出两者这些过滤器的产品。

基本上我想使用find_in_set来执行此操作:

AND (fap.filter_id = '130' AND fap.filter_id = '128')

现在它的运作方式是:

AND (fap.filter_id = '130' OR fap.filter_id = '128')

如何实现这一目标?

2 个答案:

答案 0 :(得分:1)

要解决此问题,您需要告诉sql引擎每种类型需要多少匹配结果。通常你不指定逗号分隔的元素,而是使用find_in_set在未知的元素列表中查找特定的东西。您可以轻松地将其更改为IN()语句。

WHERE p.produccts_status = 1
AND ....
AND fap.filder_id IN(130, 128)

使用提供的功能/方法编写代码是一个更好的标准。如果你愿意的话可以保留原样。

您需要添加GROUP BY p.products_id并包含一个HAVING子句来计算记录数

HAVING count(p.products_id) = 2

我在这里放2,因为你只需要找2个必须匹配的项目 您可以轻松地将其更改为您正在寻找的许多。因为你专门寻找的东西应该能够指定你想要的匹配行数(因为你在IN语句中指定了它们)

SELECT     sql_cache distinct p.products_id
FROM       products p 
INNER JOIN filter_association_products fap 
ON         p.products_id =fap.products_id 
WHERE      p.products_status = '1' 
AND        date_sub(curdate(),interval 3000 day) <= p.products_date_added 
AND        fap.filter_id IN (130, 128) 
GROUP BY   p.products_id
HAVING     COUNT(*) = 2
ORDER BY   p.products_date_added DESC

答案 1 :(得分:1)

嗯,实际上你需要这样的东西:

AND fap.filter_id IN ('130', '128')
GROUP BY p.products_id
HAVING COUNT(*) = 2

方法是让所有产品都具有两个数字,而不仅仅是完全匹配。它实际上可能更多。

但是,如果两次filter_idproducts_id相同,则无效。所以他们应该是独特的。 如果没有,请参阅here