这些日期where条件子句有什么区别?

3
这两个查询返回的订单数量不同,究竟为什么还不太清楚。第一个where子句是被认可的正确版本:
where
year(OrderDate) = 2011
and MONTH(OrderDate) = 8
and DAY(OrderDate) = 3

但是如果我说类似的话:

WHERE 
io.OrderDate >= '2011-08-03 00:00:00' 
and io.OrderDate <= '2011-08-03 11:59:59'

我得到了完全不同的记录数。是日期格式有误还是逻辑上有缺陷?我倾向于后者,因为在我看来它更易于使用。

3个回答

6

编辑:

我现在推荐的新答案结合了我的原始答案(如下所示)和 Mikael 和 Alex 的评论。

WHERE 
io.OrderDate >= '2011-08-03 00:00:00' 
and io.OrderDate < '2011-08-04 00:00:00'

应该提供所需的结果。


第二个查询仅从午夜到中午查找。(00:00:00 - 11:59:59是十二个小时)

WHERE 
io.OrderDate >= '2011-08-03 00:00:00' 
and io.OrderDate <= '2011-08-03 23:59:59'

需要修复它。

@Alex的回答也有道理。 毫秒很重要(取决于您的特定表格是否包括它们)。

WHERE 
io.OrderDate >= '2011-08-03 00:00:00.000' 
and io.OrderDate <= '2011-08-03 23:59:59.999'

将包括任何遗漏的额外记录


1
你应该尝试这个 select cast('2011-08-03 23:59:59.999' as datetime)。你的第二个版本将包括 OrderDate 是 2011-08-04 00:00:00 的行。 - Mikael Eriksson
1
@Mikael,与其强制转换,我会将其更改为您的答案建议的方法。 - Sam DeHaan
1
@Sam - 我的意思不是让你改成强制转换。这只是为了说明带有毫秒数等于999的日期时间将会四舍五入到下一天。 - Mikael Eriksson
1
@Mikael,啊,我误解了你。如果我没记错的话,这是因为SQL(至少是Server)以3ms精度存储日期时间? - Sam DeHaan
1
@Sam - 是的,没错。如果你使用了ms=998,它会四舍五入到997。 - Mikael Eriksson

4

你应该像这样做。

WHERE 
io.OrderDate >= '2011-08-03 00:00:00' 
and io.OrderDate < '2011-08-04 00:00:00'

除了查询结果的行数不同外,第一个查询将无法使用OrderDate列上的任何索引。


4

好的,11:59:59就是正午之前(也就是你提到的上午11点),这意味着你少了12个小时。

此外,请注意您还可以在DateTime中指定毫秒。因此,您可以使用'2011-08-03 23:59:59.100',它在您指定的最大OrderDate之后(即使校正为24小时制)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接