WHERE为两个日期之间的数据返回太多行

时间:2016-10-12 13:14:32

标签: mysql datetime

我想返回不在当前日期和过去7天之间的数据。

我的SELECT语句显示正常,但它也返回当天的数据。

SELECT
    customer.id AS id,
    customer.customer_id AS customer_id,
    customer.name AS name,
    customer.phone1 AS phone1,
    customer.location_area AS location_area,
    sales.post_date AS post_date 
FROM 
    sales
INNER JOIN 
    customer
ON 
    sales.customer_id = customer.customer_id
WHERE 
    post_date 
NOT BETWEEN 
   CAST( DATE_SUB(NOW(), INTERVAL 7 DAY) AS DATE )
AND 
   CAST( NOW() AS DATE )
ORDER BY 
   sales.id 
DESC
LIMIT 30

请注意,ON子句中使用的customer_id字段不是两个引用表中任何一个的主键。

我的查询可能缺少什么?

1 个答案:

答案 0 :(得分:4)

这个问题通常会导致一方面DATE数据类型的不同含义以及另一方面的TIMESTAMPDATETIME数据类型的不同含义。

我们说NOW()1-April-2017 09:35。并且,我们假设您的sales表格中有一行post_date值为1-April-2017 08:20。我们假设您的post_date列的数据类型为DATETIME

然后,在应用值后,您的WHERE子句将如下所示。

WHERE '2017-04-01 08:20' NOT BETWEEN CAST( '2017-03-25 09:35' AS DATE )
                                 AND CAST( '2017-04-01 09:35' AS DATE )

应用CAST操作,我们得到。

WHERE '2017-04-01 08:20' NOT BETWEEN '2017-03-25'
                                 AND '2017-04-01'

最后,在将DATETIMETIMESTAMPDATE值进行比较时,DATE值会被解释为具有午夜时间。所以你的查询看起来像这样:

WHERE '2017-04-01 08:20' NOT BETWEEN '2017-03-25 00:00:00'
                                 AND '2017-04-01 00:00:00'

而且,猜猜怎么着? <{1>} '2017-04-01 08:20'

你需要的是:

'2017-04-01 00:00:00'

请注意,此表达总共包含八天。

您无法使用WHERE NOT ( post_date >= CURDATE() - INTERVAL 7 DAY --on or after midnight 2016-3-25 AND post_date < CURDATE() + INTERVAL 1 DAY --before midnight 2016-04-02 ) 进行此类比较,因为您需要BETWEEN作为范围的结尾,<使用BETWEEN作为结束它的所有范围。

此外,<=CURDATE()更容易阅读。