SQL“之间”不包括在内

时间:2013-05-02 21:01:12

标签: sql sql-server sql-server-2008 tsql date

我有这样的查询:

SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'

但即使第一次有数据,这也没有结果。

created_at看起来像2013-05-01 22:25:19,我怀疑它与时间有关?怎么能解决这个问题?

如果我执行更大的日期范围,它可以正常工作,但它应该(包含)也可以使用单个日期。

9 个答案:

答案 0 :(得分:239)

包含在内。您正在将日期时间与日期进行比较。第二个日期在白天开始时被解释为午夜

解决此问题的一种方法是:

SELECT *
FROM Cases
WHERE cast(created_at as date) BETWEEN '2013-05-01' AND '2013-05-01'

另一种解决方法是使用显式二进制比较

SELECT *
FROM Cases
WHERE created_at >= '2013-05-01' AND created_at < '2013-05-02'

Aaron Bertrand在日期(here)上有一篇很长的博客文章,在那里他讨论了这个和其他日期问题。

答案 1 :(得分:36)

假设BETWEEN语法中的第二个日期引用被神奇地认为是当天的结尾&#34;但这是不真实的

即。这是预期的:

SELECT * FROM Cases 
WHERE created_at BETWEEN the beginning of '2013-05-01' AND the end of '2013-05-01'

但真正发生的是:

SELECT * FROM Cases 
WHERE created_at BETWEEN '2013-05-01 00:00:00+00000' AND '2013-05-01 00:00:00+00000'

这相当于:

SELECT * FROM Cases WHERE created_at = '2013-05-01 00:00:00+00000'

问题是关于BETWEEN的感知/期望,其中确实包括范围中的较低值和较高值,但不会神奇地约会&#34;开始&#34;或&#34;结束&#34;。

按日期范围过滤时,应避免使用

BETWEEN

始终使用>= AND <代替

SELECT * FROM Cases 
WHERE (created_at >= '20130501' AND created_at < '20130502')

括号在这里是可选的,但在更复杂的查询中可能很重要。

答案 2 :(得分:15)

您需要执行以下两个选项之一:

  1. between条件中加入时间组件:... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59'(不推荐...参见最后一段)
  2. 使用不等式代替between。请注意,您必须在第二个值中添加一天:... where (created_at >= '2013-05-01' and created_at < '2013-05-02')
  3. 我个人的偏好是第二种选择。另外,Aaron Bertranda very clear explanation说明为什么要使用它。

答案 3 :(得分:5)

只需使用时间戳作为日期:

SELECT * FROM Cases WHERE date(created_at)='2013-05-01' 

答案 4 :(得分:5)

我发现将datetime字段与日期字段进行比较的最佳解决方案如下:

DECLARE @StartDate DATE = '5/1/2013', 
        @EndDate   DATE = '5/1/2013' 

SELECT * 
FROM   cases 
WHERE  Datediff(day, created_at, @StartDate) <= 0 
       AND Datediff(day, created_at, @EndDate) >= 0 

这相当于包含在内的语句,因为它包括开始日期和结束日期以及介于两者之间的日期。

答案 5 :(得分:1)

cast(created_at as date)

仅适用于2008及更新版本的SQL Server

如果您使用的是旧版本,请使用

convert(varchar, created_at, 101)

答案 6 :(得分:0)

您可以使用date()函数从日期时间中提取日期,并将结果作为包含日期提供:

SELECT * FROM Cases WHERE date(created_at)='2013-05-01' AND '2013-05-01'

答案 7 :(得分:0)

SQL查询之间的动态日期

var startDate = '2019-08-22';
var Enddate = '2019-10-22'
     let sql = "SELECT * FROM Cases WHERE created_at BETWEEN '?' AND '?'";
     const users = await mysql.query( sql, [startDate, Enddate]);

答案 8 :(得分:0)

您的代码

SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'

SQL如何读取

SELECT * FROM Cases WHERE '2013-05-01 22:25:19' BETWEEN '2013-05-01 00:00:00' AND '2013-05-01 00:00:00'

如果在默认情况下比较DateTime和Date时没有提到时间,则在您的情况下日期相同的情况下,hours:minutes:seconds将为零,但是如果您将时间created_at提前22 hours您的结束日期范围

如果上述内容明确,您可以通过多种方式解决此问题,例如将结束时间设置为结束日期,例如BETWEEN '2013-05-01' AND ''2013-05-01 23:59:59''

OR

在将日期强制转换为日期cast(created_at as date)之后,将create_at像日期'2013-05-01 22:25:19'一样强制转换为'2013-05-01 00:00:00'