0

我有一varcharmytime只用来存储时间

现在我想找出所有在 5 小时内插入的记录。

例如

Select *
from mytable
where **mytime + interval '5' hour > current_Time**
4

1 回答 1

4

'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;

在这种情况下,您实际上可能有机会寻找索引而不是扫描整个表。

于 2013-08-13T20:16:00.933 回答