2

我有一列时间记录,代表两个日期之间的差异。其中一些记录超过 24 小时。

由于时间语法不考虑 > 24 小时的时间记录,因此我不得不将这些记录转换为 varchar hh:mm:ss,如下面链接中的解决方案所述:

SQL 日期格式 [h]:mm:ss 像 Excel 一样,超过 24 小时

这很好用,但是我的问题是我现在需要将它们转换为浮点数(例如 69:00:00.0000 为 2.875)。

不幸的是,我不能使用通常建议的 datediff 来执行此操作,因为它会为超过 24 小时的记录引发“超出范围”错误。

关于如何克服这个问题的任何想法?

4

3 回答 3

2

感谢您提供有用的帖子,我接受了原始评论的建议,因为将日期之间的差异计算为数字并稍后在表示层 (Excel) 中进行转换要容易得多。

为此,我使用 DATEPART 逻辑将日、小时、分钟、秒相加,得出一个“十进制日”数字,然后使用 Excel 将其转换为 [h]:mm:ss

(例如,'2016-04-30 23:23:00' 和 '2016-04-30 23:25:00' 之间的差异是 2 分钟。这是 0.0013888833 作为十进制日,转换为 0:02:00 Excel 格式为 [h]:mm:ss)

不幸的是,我没有时间测试替代解决方案是否有效。

于 2016-10-06T09:30:52.977 回答
1

也许你可以替换 :.. 这将为您提供一个可以用PARSENAME解析的字符串(从 SQL Server 2012 开始),然后 CAST 浮动:

DECLARE @SomeTime VARCHAR(100)='69:00:00.0000'

SELECT CAST(PARSENAME(REPLACE(@SomeTime,':','.'),4)/24.00 as float)

SUBSTRINGCHARINDEX

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 中的数学知之甚少,如果您在当前解决方案中看到任何流程,请报告/建议。

于 2016-10-06T08:11:40.543 回答
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

UPDATE 同函数

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;
于 2016-10-06T07:44:47.237 回答