SQL“之间”不包括在内

我有这样的查询:

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

但即使在1日有数据,也没有结果。

created_at看起来像2013-05-01 22:25:19 ,我怀疑它必须与时间? 这怎么解决?

它工作得很好,如果我做更大的date范围,但它应该(包括)工作与一个单一的date。

包容性的。 你正在比较date和date。 当一天开始时,第二个date被解释为午夜。

解决这个问题的一个方法是:

 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在date( 这里 )有很长的博客文章,他在这里讨论这个和其他date问题。

假定BETWEEN语法中的第二个date引用神奇地被认为是“一天结束”,但这是不真实的

即这是预期的:

 SELECT * FROM个案 
 WHERE created_at'2013-05-01' 开始和 '2013-05-01' 结束 

但真正发生的是这样的:

 SELECT * FROM个案 
 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的观点/期望之一,其中包括范围内的较低值和较高值,但奇怪地将“date”或“结束”作为date。

按date范围进行筛选时应避免使用BETWEEN

总是使用>= AND <来代替

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

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

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

  1. 包括时间组件在你的条件between... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59' (不build议…见最后一段)
  2. 使用不等式而不是between 。 注意,那么你将不得不增加一天到第二个值: ... where (created_at >= '2013-05-01' and created_at < '2013-05-02')

我的个人喜好是第二种select。 另外, Aaron Bertrand对于为什么要使用这个问题有一个非常明确的解释 。

只需使用时间戳作为date:

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

我发现将date时间字段与date字段进行比较的最佳解决scheme如下所示:

 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 

这相当于一个包含性的声明,因为它包括开始和结束date以及其间的内容。

作为备选:

 SELECT * FROM Cases WHERE convert(varchar, created_at, 120) Like '2013-05-01%' 
 cast(created_at as date) 

这将只在2008年和更新版本的SQL Server工作

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

 convert(varchar, created_at, 101)