SQL选择查询日期/时间列的奇怪行为

时间:2017-05-17 22:58:59

标签: sql sql-server sql-server-express

我在SQL Server Express中遇到一个奇怪的问题,希望有人可以解释为什么我遇到这种行为以及正确的做法。

当我运行此查询时,它会返回我期望的内容:

SELECT 
    Action, TimeOccurred, UserName, IPv4From, ShareName, 
    FullFilePath, NewPathName, FromServer 
FROM 
    File_System_Profiles 
WHERE
    Action LIKE '%create%' 
    AND (TimeOccurred >= '04/27/2017')

所有这些来自4/27以及之后的任何内容。

当我运行此查询时,它返回0结果,这是非常奇怪的,因为在上一个查询的结果中有4/27的条目:

SELECT 
    Action, TimeOccurred, UserName, IPv4From, ShareName, 
    FullFilePath, NewPathName, FromServer 
FROM 
    File_System_Profiles 
WHERE
    Action LIKE '%create%' 
    AND (TimeOccurred = '04/27/2017')

我删除的只是> =和日期之间我没有结果。我可以清楚地看到,当我运行第一个查询时,结果显示04/27/2017是某事发生的日期。如果第一个查询不起作用,我会假设我的日期格式MM/DD/YYYY存在问题,而YYYY-MM-DD HH:MM:SS列实际上是什么,但是因为第一个查询有效,所以第二个查询似乎合乎逻辑应该。

2 个答案:

答案 0 :(得分:1)

这是日期格式的问题。正如您所提到的,您使用日期格式为"YYYY-MM-DD HH:MM:SS",因此您应该知道在比较中使用值"04/27/2017"将被视为"04/27/2017 00:00:00"

我假设您没有记录日期字段中的值为"04/27/2017 00:00:00"的位置,这就是为什么当您使用=运算符时,它与任何记录都不匹配。但是,操作员>=选择记录,其中小时:分钟:日期的第二部分存在。作为一个例子" 04/27/2017 01:10:00" 00/00:00"大于" 04/27/2017 00:00:00"因此>运算符会提取这些记录。

希望它有所帮助。

答案 1 :(得分:1)

首先,始终使用ISO标准格式进行比较。您的代码看起来应该更像这样:

where Action LIKE '%create%' AND 
      TimeOccurred = '2017-04-27'

Nauman解释了这个问题,即TimeOccurred上的时间组件。您可以通过各种方式解决此问题。一种方法是转换为日期。像这样:

where Action LIKE '%create%' AND 
      cast(TimeOccurred as date) = '2017-04-27'

cast()可能会被trunc()date_trunc()或其他内容替换,具体取决于数据库。

但是,我更喜欢这个版本:

where Action LIKE '%create%' AND 
      TimeOccurred >= '2017-04-27' AND
      TimeOccurred < '2017-04-28' 

它触及问题的核心。而且 - 更好的是 - SQL优化器可以使用索引。