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 优化器可以利用索引。
我在 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 优化器可以利用索引。