我有2个查询:
SELECT sql_cache distinct p.products_image,
p.products_subimage1,
pd.products_name,
p.products_quantity,
p.products_model,
p.products_ordered,
p.products_id,
p.products_price,
p.products_date_added,
p.products_weight,
p.products_length,
p.products_width,
p.products_height,
p.products_tax_class_id,
p.products_status,
IF(s.status, s.specials_new_products_price, NULL) AS specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) AS final_price
FROM products p
LEFT JOIN specials s
ON p.products_id = s.products_id
LEFT JOIN products_to_categories p2c
ON p.products_id=p2c.products_id
LEFT JOIN products_description pd
ON p.products_id=pd.products_id
INNER JOIN filter_association_products fap
ON p.products_id =fap.products_id
LEFT JOIN products_attributes pa
ON p.products_id = pa.products_id
WHERE p.products_status = '1'
AND date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added
AND fap.filter_id = 126
ORDER BY p.products_date_added DESC,
pd.products_name
这给了我52行(产品)的结果。
相同的查询只有差异:
AND fap.filter_id = 130
这给了我4行的结果。
这些行/产品之间的一个常见问题是4个filter_id
130中的3个也有filter_id
126我想修改查询以仅向我提供产品的结果两者(甚至更多,取决于所应用的filter_id
)filter_id
。
我试过了
...
AND FIND_IN_SET(fap.filter_id,'126', '130')
ORDER BY p.products_date_added DESC, pd.products_name
但是我获得了53行/产品的结果,这意味着它显示了所有具有过滤器的产品,而我在这种情况下寻找的结果只有3行同时具有filter_id
。
重写查询以获得正确结果的最佳方法是什么?
答案 0 :(得分:2)
使用GROUP BY
获取所需的产品信息。您也可以加入其他信息,但这是基本查询:
SELECT p.*
FROM products p JOIN
specials s
ON p.products_id = s.products_id JOIN
products_to_categories p2c
ON p.products_id = p2c.products_id JOIN
products_description pd
ON p.products_id = pd.products_id JOIN
filter_association_products fap
ON p.products_id = fap.products_id JOIN
products_attributes pa
ON p.products_id = pa.products_id
WHERE p.products_status = '1' AND
date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added AND
fap.filter_id IN (126, 130)
GROUP BY p.products_id
HAVING COUNT(DISTINCT fap.filter_id) = 2; -- make sure both match
我认为LEFT JOIN
没有任何理由(至少对于大多数表格而言,因为filter_association_products
之前的所有内容都被WHERE
转换为内部联接(),所以我把它们改成了内连接。
答案 1 :(得分:1)
在filter_association_products上制作两个LEFT JOIN
并在WHERE
中过滤,如下所示:
SELECT sql_cache distinct p.products_image,
p.products_subimage1,
pd.products_name,
p.products_quantity,
p.products_model,
p.products_ordered,
p.products_id,
p.products_price,
p.products_date_added,
p.products_weight,
p.products_length,
p.products_width,
p.products_height,
p.products_tax_class_id,
p.products_status,
IF(s.status, s.specials_new_products_price, NULL) AS specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) AS final_price
FROM products p
LEFT JOIN specials s
ON p.products_id = s.products_id
LEFT JOIN products_to_categories p2c
ON p.products_id=p2c.products_id
LEFT JOIN products_description pd
ON p.products_id=pd.products_id
LEFT JOIN filter_association_products fap1
ON p.products_id =fap1.products_id
LEFT JOIN filter_association_products fap2
ON p.products_id =fap2.products_id
LEFT JOIN products_attributes pa
ON p.products_id = pa.products_id
WHERE p.products_status = '1'
AND date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added
AND fap1.filter_id = 126
AND fap2.filter_id = 130
ORDER BY p.products_date_added DESC,
pd.products_name
另一种方法(子选择):
SELECT sql_cache distinct p.products_image,
p.products_subimage1,
pd.products_name,
p.products_quantity,
p.products_model,
p.products_ordered,
p.products_id,
p.products_price,
p.products_date_added,
p.products_weight,
p.products_length,
p.products_width,
p.products_height,
p.products_tax_class_id,
p.products_status,
IF(s.status, s.specials_new_products_price, NULL) AS specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) AS final_price
FROM products p
LEFT JOIN specials s
ON p.products_id = s.products_id
LEFT JOIN products_to_categories p2c
ON p.products_id=p2c.products_id
LEFT JOIN products_description pd
ON p.products_id=pd.products_id
LEFT JOIN products_attributes pa
ON p.products_id = pa.products_id
WHERE p.products_status = '1'
AND date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added
AND 126 in (select fap1.filter_id from filter_association_products fap1
where p.products_id = fap1.products_id)
AND 130 in (select fap2.filter_id from filter_association_products fap2
where p.products_id = fap2.products_id)
ORDER BY p.products_date_added DESC,
pd.products_name
答案 2 :(得分:1)
虽然Mikey和Gordon Linoff的答案都很好,但由于其可扩展性,我更倾向于Gordon的方法。但是,他的答案有一些语法错误,切换到JOINs没有产生任何结果,因此我不得不将它们修改为LEFT JOIN,如Mikey所建议的那样。 (谢谢你们俩)。 这是最终的查询:
SELECT sql_cache distinct p.products_image,
p.products_subimage1,
pd.products_name,
p.products_quantity,
p.products_model,
p.products_ordered,
p.products_id,
p.products_price,
p.products_date_added,
p.products_weight,
p.products_length,
p.products_width,
p.products_height,
p.products_tax_class_id,
p.products_status,
IF(s.status, s.specials_new_products_price, NULL) AS specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) AS final_price
FROM products p
LEFT JOIN specials s
ON p.products_id = s.products_id
LEFT JOIN products_to_categories p2c
ON p.products_id=p2c.products_id
LEFT JOIN products_description pd
ON p.products_id=pd.products_id
INNER JOIN filter_association_products fap
ON p.products_id =fap.products_id
LEFT JOIN products_attributes pa
ON p.products_id = pa.products_id
WHERE p.products_status = '1'
AND date_sub(curdate(),INTERVAL 3000 day) <= p.products_date_added
AND fap.filter_id IN (126, 130)
GROUP BY p.products_id
HAVING COUNT(DISTINCT fap.filter_id) = 2;