SQL Select 查询 Date/Time 列的奇怪行为

SQL Select Query on Date/Time column strange behavior

我在 SQL Server Express 中遇到一个关于 select 语句的奇怪问题,希望有人能阐明我为什么会遇到这种行为以及正确的做法它。

当我 运行 这个查询时 returns 正是我所期望的:

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

4 月 27 日及之后的所有条目。

当我 运行 这个查询时 returns 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 列中的实际内容有问题,但由于第一个查询有效,所以第二个查询似乎合乎逻辑应该。

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

我假设您没有日期字段中值为 "04/27/2017 00:00:00" 的记录,这就是为什么当您使用 = 运算符时,它不匹配任何记录。但是,运算符 >= 会选择 hour:minute:second 部分日期存在的记录。例如,“04/27/2017 01:10:00”大于“04/27/2017 00:00:00”,因此 > 运算符获取这些记录。

希望对您有所帮助。

首先,始终使用 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 优化器可以利用索引。