0

我得到的部分任务涉及对几列执行计算,其中 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,我已经为此苦苦挣扎了几个小时。尽管听起来很可怕,但我现在对它的工作感到满意,即使这意味着牺牲性能。

4

3 回答 3

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.57.46”的输入,12.970 是错误的。问题是您错误地使用了 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 个字符。

顺便说一句,我会像 Gordon 那样解决这个问题,只是我会删除日期内容,所以它看起来像这样:

Select DateDiff(Second, 
                0, 
                Convert(DateTime, Replace([OASTIM], '.',':'))) / 3600.0
于 2014-03-22T21:22:08.957 回答
0

您没有解释什么是“时间小数”格式。从你的例子中,我猜你的意思是十进制小时。

SQL Server 中用于日期差异的一个关键函数是datediff(). 您可以使用技巧将时间转换为秒。将时间添加到date,然后用于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/20,而不是0.5

于 2014-03-21T20:23:44.900 回答
0

这是将时间转换为 DecimalHours 的简单方法。

SELECT cast(cast('12.57:46' as datetime) as float) * 24

结果:

~12.963
于 2014-03-22T19:08:39.777 回答