我有一个DateTime列。我想在一定日期范围内从8:30到16:15提取所有记录。我的问题是我需要将小时和分钟作为单个时间值进行比较。我可以测试DATEPART大于或小于几个小时的值,但如果我这样做了几分钟,如果当天晚些时间的分钟值较小,我的查询将失败。
我已经查看了INTERVAL,BETWEEN,DATEPART,DATEDIFF等,但是如果没有“TimeOfDay”值可以在不同日期的记录中使用,那么就看不到如何做到这一点。
我已经尝试减去日期的年,月和日部分,这样我就可以只比较一天中的时间,但是当试图减去日期部分时,我会得到一个过度错误:
这部分有效:
select - cast( DATEPART(YEAR, CallTime) as integer) from history
这失败了:
select DATEADD(YEAR, - cast( DATEPART(YEAR, CallTime) as integer), CallTime)
from history where calltime is not null
我还尝试将小时和分钟部分投射到字符,连接它们并与我的目标范围进行比较,但这也失败了。
我相信较新版本的SQL服务器可能具有处理这种情况的功能,但我无法使用。
我希望并想象有一个简单明了的解决方案,但它让我望而却步。
答案 0 :(得分:2)
尝试创建一个“MinuteOfDay”函数,该函数根据日期时间计算当天经过的分钟数。
CREATE FUNCTION dbo.[MinuteOfDay]
(
@dt datetime
)
RETURNS int
AS
BEGIN
RETURN (datepart(hh,@dt)*60) + datepart(mi,@dt)
END
然后使用该函数的结果进行过滤。
select *
from MyTable t
where dbo.MinuteOfDay(t.SomeDateTimeColumn) between dbo.MinuteOfDay('1900-1-1 08:30:00') and dbo.MinuteOfDay('1900-1-1 16:15:00')
答案 1 :(得分:0)
试一试:
DECLARE @StartDateTime datetime
,@EndDateTime datetime
--date range is ALL of January 1st up to & including 31st
SELECT @StartDateTime='2011/01/01'
,@EndDateTime='2011/01/31'
SELECT
*
FROM TableName t
WHERE
t.ColumnDate>=@StartDateTime AND t.ColumnDate<@EndDateTime+1 --date range
AND LEFT(RIGHT(CONVERT(char(19),t.ColumnDate(),120),8),5)>='08:30' --time range start
AND LEFT(RIGHT(CONVERT(char(19),t.ColumnDate(),120),8),5)<='16:15' --time range end
如果你有关于t.ColumnDate的索引,这应该可以利用它。
WHERE的“日期范围”部分会丢弃不在预期日期范围内的行。 WHERE的“时间范围开始”部分抛弃了早期的行,“时间范围结束”抛弃了迟到的行。
答案 2 :(得分:0)
DATETIME值可以转换为FLOAT。实际上,DATETIME存储为FLOAT。
FLOAT的整个部分是自'12 / 31/1899'以来的日子(或接近)。小数部分是小时数除以24.所以0.5 = 12中午。
08:30是0.3541666667
16:15是0.6770833333
选择CAST(CAST('2011-03-25 08:30:00'作为DATETIME)作为FLOAT)= 40625.3541666667
选择CAST(CAST('2011-03-25 16:15:00'AS DATETIME)as FLOAT)= 40625.6770833333
所以你可以写
SELECT * FROM users WHERE hire_date&lt; 40625.3541666667
使用DATETIME作为FLOAT,您可以使用最适合您查询的数学函数。