我有一varchar
列mytime
只用来存储时间
现在我想找出所有在 5 小时内插入的记录。
例如
Select *
from mytable
where **mytime + interval '5' hour > current_Time**
我有一varchar
列mytime
只用来存储时间
现在我想找出所有在 5 小时内插入的记录。
例如
Select *
from mytable
where **mytime + interval '5' hour > current_Time**
'floob'
由于如果有人填充或在列中,隐式转换到日期时间可能会失败'32:45'
- 他们可能会因为,你知道,它是错误的数据类型 - 你需要处理这种情况并处理任何已经潜入其中的坏数据。您还需要将时间值标准化为同一日期,因为没有日期的时间将具有日期组件,1900-01-01
但涉及添加/减去小时数的任何内容都GETDATE()
将具有今天日期的日期组件。所以你需要这样的东西来处理所有这些(这假设你的时间被简单地存储12:32
而不是12:32.000
或包括AM
/ PM
):
-- first, get a variable to hold 5 hours ago on 1900-01-01:
DECLARE @cutoff DATETIME;
SET @cutoff = DATEADD(DAY,-DATEDIFF(DAY,0,GETDATE()),DATEADD(HOUR,-5,GETDATE()));
-- now use that in the WHERE clause
-- and also check that the value can be converted
-- to a date and it is in hh:mm format.
-- need CASE expression here because you can't
-- control the order in which WHERE clauses are
-- evaluated by SQL Server.
SELECT ... WHERE
CASE
WHEN ISDATE(MyTime) = 1
AND MyTime LIKE '[ 0-2][0-6]:[0-6][0-9]'
THEN CONVERT(DATETIME, MyTime) END > @cutoff;
在 SQL Server 2008 及更高版本中,您可以使用TIME
数据类型,因此您无需担心合并日期。而在 SQL Server 2012 及更高版本中,您可以使用它TRY_CONVERT
来避免所有那些混乱的CASE
逻辑。
真正的答案:修复列并使用正确的数据类型。绝对没有理由将时间数据存储在字符串列中。然后你可以说:
WHERE MyTime > @cutoff;
在这种情况下,您实际上可能有机会寻找索引而不是扫描整个表。