我获得的部分任务涉及对几列进行计算,其中2列的格式为hh.mi.ss,它们是varchar。为了使计算起作用,我需要将它们变成时间十进制格式,其中1:30为1.5。由于我目前正在使用SQL Server 2005,我没有内置的时间或数据类型,我无法获得升级版本(不是我的选择)。使用我的工作,我在网上搜索并尝试转换它,但结果不准确。例如,13.28变为(大致)13.5,这很好,但是,秒数变为100而不是结束于60(因为我将它转换为浮点数)。
例如,使用12.57.46,
CAST(DATEPART(HH, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT) +
(CAST(DATEPART(MI, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT)/60) +
(CAST(DATEPART(SS, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME)) AS FLOAT)/3600)
给了我12.962 ......
而
CAST(SUBSTRING([OASTIM], 1, 2) AS FLOAT) +
((CAST(SUBSTRING([OASTIM], 4, 5) AS FLOAT) +
CAST(SUBSTRING([OASTIM], 7, 8) AS FLOAT)/60)/60)
给了我12.970 ....
当我尝试更简单的事情时,
DATEPART(HOUR, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME))+
(DATEPART(MINUTE, CAST(REPLACE([OASTIM], '.', ':') AS DATETIME))/60)
失败了,只给了我12个
这是我第一次接触Windows SQL和T-SQL,我几个小时一直在努力。虽然听起来很可怕,但我对它的工作非常满意,即使它意味着牺牲性能。
答案 0 :(得分:0)
您没有解释什么是“时间十进制”格式。从你的例子中,我猜你的意思是十进制小时数。
SQL Server中用于日期差异的关键功能是datediff()
。您可以使用技巧将时间转换为秒。将时间添加到日期,然后使用datediff()
获取午夜后的秒数。之后,转换为十进制小时只是算术。
以下是一个例子:
select datediff(second,
cast('2000-01-01' as datetime),
cast('2000-01-01 ' + '00:00:59' as datetime)
)/3600.0 as DecimalHours
请注意使用常量3600.0
。小数点非常重要,因为SQL Server对整数输入进行整数除法。因此,1/2
是0
,而不是0.5
。
答案 1 :(得分:0)
这是一种将时间转换为DecimalHours的简单方法。
SELECT cast(cast('12.57:46' as datetime) as float) * 24
结果:
~12.963
答案 2 :(得分:0)
你说,
CAST(SUBSTRING([OASTIM], 1, 2) AS FLOAT) +
((CAST(SUBSTRING([OASTIM], 4, 5) AS FLOAT) +
CAST(SUBSTRING([OASTIM], 7, 8) AS FLOAT)/60)/60)
给了我12.970 ....
12.970输入' 12.57.46'是错误的。问题是您正在错误地使用SUBSTRING功能。第三个参数表示字符数,而不是结束字符位置。
看看这段代码:
声明@Sample varchar(20)
设置@Sample =' 12.57.46'
select CAST(SUBSTRING(@Sample, 1, 2) AS FLOAT) +
CAST(SUBSTRING(@Sample, 4, 5) AS FLOAT) / 60 +
CAST(SUBSTRING(@Sample, 7, 8) AS FLOAT) / 60 / 60,
SUBSTRING(@Sample, 1, 2),
SUBSTRING(@Sample, 4, 5),
SUBSTRING(@Sample, 7, 8),
CAST(SUBSTRING(@Sample, 1, 2) AS FLOAT) +
CAST(SUBSTRING(@Sample, 4, 2) AS FLOAT) / 60 +
CAST(SUBSTRING(@Sample, 7, 2) AS FLOAT) / 60 / 60
请注意,会议记录为57.46,因为您要求5个字符。秒数正确显示,因为尽管您要求8个字符,但字符串中只剩下2个字符,因此只返回2个字符。
顺便说一下,我会像戈登那样解决这个问题,除非我删除日期内容,所以它看起来像这样:Select DateDiff(Second,
0,
Convert(DateTime, Replace([OASTIM], '.',':'))) / 3600.0