在SQL Server T-SQL中比较日期/时间

3
我们的表中,每一行都存储了一个格式为“2013-05-26 20:22:07.2894”的日期/时间变量。我们该如何在T_SQL WHERE语句中使用这个列来检索最近1小时的行?我们尝试了以下代码并且它可行:WHERE Time_Stamp > '2013-05-26 18:00:00:0000',但我们希望T-SQL能够自动处理而不是硬编码日期和时间。请帮忙解决。

1
你为什么要将它存储为 varchar - Martin Smith
这是我从前任手中继承下来的东西。 - Adam Chetnik
1
你考虑过 alter table <t> alter column Time_Stamp datetime 吗? - Gordon Linoff
1
不良习惯需要改掉:选择错误的数据类型 - 你应该始终使用最合适的数据类型 - 毕竟这就是它们存在的原因! - marc_s
4个回答

4
这里有一个可sargable的方法(意味着它会使用索引):
where Time_Stamp > convert(varchar(255), getdate() - 1.0/24, 121)

@Adam...很高兴我能帮到你。 - Gordon Linoff

1
要将您的 VARCHAR 转换为 DATETIME,只需使用以下代码;
CONVERT(DATETIME, SUBSTRING(myDate, 1, 23), 121);

...其中myDate是您的列名称。一旦将其转换为datetime,与GETDATE()进行比较就很简单。

一个非常简单的SQLfiddle


0
你可以将getdate()dateadd()结合起来,从当前时间减去1小时:
WHERE Time_Stamp > dateadd(hour, -1, getdate())

因为datetime的优先级更高,所以varchar将被转换为datetime进行比较。


1
在这种情况下,将 varchar 转换为 datetime 是不利的,因为它会使 WHERE 无法被优化。 - Martin Smith
这会导致一个错误: Msg 241,级别16,状态1,第2行 将日期和/或时间从字符字符串转换失败。 - Adam Chetnik
@MartinSmith:可能是对的,但问题并没有说Time_Stamp列有索引。即使有索引,SQL Server也不太可能使用一个非覆盖索引来处理<条件。 - Andomar
@Andomar - 这取决于临界点。即使表中只有4天的数据,检索“最近1小时的所有行”仍然只占表的约1%,SQL Server可能更喜欢具有查找而非扫描整个表的计划。 - Martin Smith
@MartinSmith:根据我的经验,临界点在100行或更多。无论如何,我认为用关于可排序性的低级细节来回答初学者关于日期的问题有些奇怪。 - Andomar

0
Datediff(hour, time_stamp, getdate()) < 1

但是,您可能在将时间戳存储为varchar时犯了一个错误。当您将其存储为varchar时,SQL将不得不检查表上的每个候选行以查找记录,并且它将不得不将每个timestamp值转换为dateline,以便能够识别您要查找的记录。希望您的查询条件只需要检查少量记录。

但实际上,没有理由将日期存储为字符串。将它们存储为datetime占用更少的空间,查询速度更快,并且可能允许SQL选择更好的查询计划。隐藏服务器的值的本质只会阻止它帮助您,并使您必须担心当字段值为“Hello”而不是“2013-05-26 18:00:00:0000”时会发生什么。您应该将日期存储为Datetime,并为其构建适当的索引(您需要的索引详细信息需要比您提供的系统更多的信息)。


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