Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从时间转换为十进制时间时出现问题_Sql_Sql Server_Tsql_Datetime Conversion - Fatal编程技术网

Sql 从时间转换为十进制时间时出现问题

Sql 从时间转换为十进制时间时出现问题,sql,sql-server,tsql,datetime-conversion,Sql,Sql Server,Tsql,Datetime Conversion,我完成的部分任务涉及对几个列执行计算,其中两列的格式为hh.mi.ss,它们是varchar。为了使计算有效,我需要将它们转换为时间十进制格式,即1:30为1.5。由于我目前使用的是SQL Server 2005,因此我没有内置的时间或数据类型,无法获得升级版本(不是我的选择)。利用我所拥有的,我在网上四处搜索并试图转换它,但结果并不准确。例如,13.28变为(大致)13.5,这很好,但是秒数变为100而不是60(因为我将它转换为浮点) 例如,使用12.57.46 CAST(DATEPART(H

我完成的部分任务涉及对几个列执行计算,其中两列的格式为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,我已经为此挣扎了几个小时。虽然听起来很可怕,但我已经到了这样一个地步,我很高兴它能工作,即使这意味着牺牲性能

您没有解释什么是“时间小数”格式。根据你的例子,我猜你指的是十进制小时

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
的使用。小数点非常重要,因为SQLServer对整数输入进行整数除法。因此,
1/2
0
,而不是
0.5

这里有一个将时间转换为小数小时的简单方法

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

~12.963
你说

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”是错误的。问题是您使用的子字符串函数不正确。第三个参数表示字符数,而不是结束字符的位置

请看下面的代码:

声明@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

我注意到您使用的是日期,我有一个与我的时间列相对应的日期列(是的,它们是分开的,两者都是varchar,但日期的格式是YYYY-MM-DD)。当我指的是“时间十进制格式”时,我指的是十进制小时。@buckooooo。这使用任意日期只是为了方便地将时间转换为秒。除非你出于某种原因需要,否则它不会使用日期栏。我从老板那里得到了最新消息,他确实希望我将日期纳入我的计算中。我放弃了我的子字符串方法,决定将你的方法用于datediff,因为它更干净。在我做了一些手动计算以进行比较之后,结果是正确的,所以我接受了你的答案。@G Mastros啊,我知道我在哪里胡闹了,谢谢!顺便说一句,我的老板告诉我最新情况,他希望我把日期纳入我的计算中。例如,如果时间相同但日期不同,则结果不应为0,而应为这两个日期之间的十进制小时数。我想我是用datediff函数实现的,因为它看起来比使用子字符串更简洁。