JBu*_*ace 117 sql t-sql sql-server date sql-server-2008
我有这样的查询:
SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'
Run Code Online (Sandbox Code Playgroud)
但即使第一次有数据,这也没有结果.
created_at看起来2013-05-01 22:25:19,我怀疑它与时间有关?怎么解决这个问题?
如果我执行更大的日期范围,它可以正常工作,但它应该(包含)也可以使用单个日期.
Gor*_*off 261
它是包容性的.您正在将日期时间与日期进行比较.第二个日期被解释为当天开始时的午夜.
解决此问题的一种方法是:
SELECT *
FROM Cases
WHERE cast(created_at as date) BETWEEN '2013-05-01' AND '2013-05-01'
Run Code Online (Sandbox Code Playgroud)
另一种解决方法是使用显式二进制比较
SELECT *
FROM Cases
WHERE created_at >= '2013-05-01' AND created_at < '2013-05-02'
Run Code Online (Sandbox Code Playgroud)
Aaron Bertrand在日期(这里)有一篇很长的博客文章,在那里他讨论了这个和其他日期问题.
Use*_*ady 39
假设BETWEEN语法中的第二个日期引用被神奇地认为是"一天的结束",但这是不真实的.
即这是预期的:
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其中不包括两个较低的值,并在范围的上限的值,但并不神奇地让一个日期或者"结束""的开始".
BETWEEN 按日期范围过滤时应避免使用.
总是用>= AND <而不是
SELECT * FROM Cases WHERE (created_at >= '20130501' AND created_at < '20130502')
括号在这里是可选的,但在更复杂的查询中可能很重要.
Bar*_*nka 16
您需要执行以下两个选项之一:
between条件中包含时间组件:( ... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59'不推荐...参见最后一段)between.请注意,那么您必须在第二个值中添加一天:... where (created_at >= '2013-05-01' and created_at < '2013-05-02')我个人的偏好是第二种选择.此外,Aaron Bertrand对为何应该使用它有一个非常明确的解释.
只需将时间戳记用作日期:
SELECT * FROM Cases WHERE date(created_at)='2013-05-01'
Run Code Online (Sandbox Code Playgroud)
小智 6
我发现将datetime字段与date字段进行比较的最佳解决方案是:
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
Run Code Online (Sandbox Code Playgroud)
这等效于包含之间的语句,因为它既包含开始日期也包含结束日期以及介于两者之间的日期。