使用内部联接时,HAVING子句未过滤所有条件

问题描述

谁能告诉我为什么这个陈述不将结果限制在今天和过去7天?它向我显示了3个月前的结果以及今天的结果。在另一篇文章中,我被告知我必须从WHERE子句更改为HAVING子句。与%trans%中的变量有关吗?

SELECT a.`post_id`,b.`name`,MAX(case when Meta_key = 'value' THEN `Meta_value` ELSE NULL END) as  'Email',MAX(CASE WHEN `Meta_key` = 'value' THEN `Meta_value` ELSE NULL END) as 

FROM table_1 a
INNER JOIN table_2 b ON FIND_IN_SET(a.post_id,b.payment_ids) 
GROUP BY a.post_id 
HAVING DeliveryDate = (DATE_SUB(CURDATE(),INTERVAL 7 DAY)) AND DeliveryType = 'pickup' AND  OrderStatus = 'ready' OR OrderStatus = 'transit'  
ORDER BY 'DeliveryTime'  DESC

解决方法

这是您的代码:

DeliveryDate = (DATE_SUB(CURDATE(),INTERVAL 7 DAY)) 
AND DeliveryType = 'pickup' 
AND  OrderStatus = 'ready' 
OR OrderStatus = 'transit'

您有一个逻辑优先级问题。 OR的优先级低于AND,因此,其内容为:

(
    DeliveryDate = (DATE_SUB(CURDATE(),INTERVAL 7 DAY)) 
    AND DeliveryType = 'pickup' 
    AND  OrderStatus = 'ready' 
)
OR OrderStatus = 'transit'

现在可以很容易地看出,这允许任何行处于“转换”状态,而不管其传递类型或日期如何。

您需要在OR条件周围加上括号-或更简单些,请使用IN

DeliveryDate = (DATE_SUB(CURDATE(),INTERVAL 7 DAY)) 
AND DeliveryType = 'pickup' 
AND OrderStatus IN ('ready','transit')

注意:

  • 将这些条件放在WHERE而非HAVING子句中会更有意义,因为它们不适用于聚合列

  • DATE_SUB(CURDATE(),INTERVAL 7 DAY)可以简化为current_date - interval 7 day