我有一个包含时间记录的列,表示两个日期之间的差异。其中一些记录超过24小时。
由于时间语法不考虑时间记录> 24小时,我必须将这些记录转换为varchar hh:mm:ss,如以下链接中的解决方案所述:
SQL date format [h]:mm:ss like Excel does, beyond 24 hr
这很好用,但我的问题是我现在需要将它们转换为浮点数(例如69:00:00.0000为2.875)。
不幸的是,我不能使用通常建议的约会,因为它会超过24小时的记录引发“超出范围”错误。
关于如何克服这个问题的任何想法?
答案 0 :(得分:2)
感谢有用的帖子,我接受了原始评论的建议,因为它更容易计算日期之间的差异作为数字,并稍后在表示层(Excel)中进行转换。
为此,我使用DATEPART逻辑将日,小时,分钟,秒组合在一起,得出一个小数日'然后使用Excel将其转换为[h]:mm:ss
(例如,2016-04-30 23:23:00' 2016-04-30 23:25:00'之间的差异是2分钟。这是0.0013888833 as十进制日,格式为[h]时转换为Excel中的0:02:00:mm:ss)
不幸的是,我没有时间测试替代解决方案是否有效。
答案 1 :(得分:1)
这样的东西?
DECLARE @YourTime VARCHAR(100)='69:00:00.0000';
WITH Splitted AS
(
SELECT @YourTime AS t
,CHARINDEX(':',@YourTime)-1 AS HourLength
,LEFT(@YourTime,CHARINDEX(':',@YourTime)-1) AS HourPart
)
SELECT HourPart/24 + CAST(CAST(CAST(STUFF(@YourTime,1,HourLength,HourPart-(HourPart/24)*24) AS TIME) AS DATETIME) AS FLOAT)
FROM Splitted
CREATE FUNCTION dbo.ConvertExceedingTimeToFloat(@TimeString VARCHAR(100))
RETURNS FLOAT
AS
BEGIN
DECLARE @RetVal FLOAT;
WITH Splitted AS
(
SELECT @TimeString AS t
,CHARINDEX(':',@TimeString)-1 AS HourLength
,LEFT(@TimeString,CHARINDEX(':',@TimeString)-1) AS HourPart
)
SELECT @RetVal = HourPart/24 + CAST(CAST(CAST(STUFF(@TimeString,1,HourLength,HourPart-(HourPart/24)*24) AS TIME) AS DATETIME) AS FLOAT)
FROM Splitted;
RETURN @RetVal;
END
GO
SELECT dbo.ConvertExceedingTimeToFloat('69:00:00.0000')
GO
DROP FUNCTION dbo.ConvertExceedingTimeToFloat;
答案 2 :(得分:1)
也许你可以REPLACE :
到.
。这将为您提供一个可以使用PARSENAME(从SQL Server 2012开始)解析的字符串,然后CAST浮动:
DECLARE @SomeTime VARCHAR(100)='69:00:00.0000'
SELECT CAST(PARSENAME(REPLACE(@SomeTime,':','.'),4)/24.00 as float)
SELECT CAST(SUBSTRING(@SomeTime,1,CHARINDEX(':',@SomeTime)-1)/24.00 as float)
输出:
2,875
希望,我的问题是对的。
修改强>
上述方法仅使用了几个小时。如果你需要更深入:
DECLARE @SomeTime VARCHAR(100)='69:55:10.999',
@x xml
--Convert to XML
SELECT @x = CAST('<p>'+REPLACE(REPLACE(@SomeTime,':','.'),'.','</p><p>') +'</p>' as xml)
--Working with XML, each part need convertion
SELECT CAST(
t.c.value('/p[1]','int')/24.00+
(t.c.value('/p[2]','int')/60.00)/24.00+
((t.c.value('/p[3]','int')/60.00)/60.00)/24.00+
(((t.c.value('/p[4]','int')/1000.00)/60.00)/60.00)/24.00
as float) result
FROM @x.nodes('/') as t(c)
输出:
2,9133217194375
注意:
我对SQL Server中的MATH了解不多,请报告/建议您是否在当前解决方案中看到任何流程。