5

我在表中有一个列,将分钟数存储为numeric(18,4)名为[course_access_minutes].

存储的值来自黑板数据库,如下所示:

0.0500
0.0667
0.3667
up to 
314.0833
625.8167

如何将这些转换为时间 hh:mm,我已经很好地查看了数据库文档,我能找到的只是

course_access_minutes numeric(18,4) 这是用户在此登录会话期间访问此课程的总分钟数。

我可以假设我可以将几分钟直接转换为几小时吗?我想我会将任何低于 1 的值视为 0 分钟。在 SQL 中执行此操作的最佳方法是什么?在此先感谢您的帮助。

4

4 回答 4

9

尝试这个

SELECT CONVERT(varchar, DATEADD(s, 625.8167 * 60, 0), 108)

如果持续时间超过 24 小时,您可以使用此

SELECT CONVERT(varchar, CAST(1877.4501 * 60 AS int) / 3600) 
    + RIGHT(CONVERT(varchar, DATEADD(s, 1877.4501 * 60, 0), 108), 6)
于 2017-05-26T13:50:42.260 回答
1
WITH _Samples AS (
    SELECT CONVERT(numeric(18, 4), 0.0500) [course_access_minutes]
    UNION ALL SELECT 0.0667
    UNION ALL SELECT 0.3667
    UNION ALL SELECT 314.0833
    UNION ALL SELECT 625.8167
) 
SELECT 
    S.course_access_minutes, 

    -- split out the number
    FLOOR(S.course_access_minutes / 60) [hours], 
    FLOOR(S.course_access_minutes % 60) [minutes], 
    FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60) [seconds], 

    -- to a string
    CONVERT(varchar(10), FLOOR(S.course_access_minutes / 60)) 
    + ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR(S.course_access_minutes % 60)), 2)
    + ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60)), 2) [time_string], 

    -- You could consider converting to the time data type if the values will never exceed the limit
    -- time supports 00:00:00.0000000 through 23:59:59.9999999
    -- 0 through 1439.9833333 ... 23 * 60 = 1380 + 59 = 1439 + (59 / 60) = 1439.9833333 
    -- (see: https://docs.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql)
    CONVERT(time, 
        CONVERT(varchar(10), FLOOR(S.course_access_minutes / 60)) 
        + ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR(S.course_access_minutes % 60)), 2)
        + ':' + RIGHT('00' + CONVERT(varchar(10), FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60)), 2) 
    ) [time]
FROM 
    _Samples S 

(进一步推进这个想法并拆分小数秒并不难。)

产生:

course_access_minutes  hours  minutes  seconds  time_string  time
---------------------- ------ -------- -------- ------------ ----------------
0.0500                 0      0        3        0:00:03      00:00:03.0000000
0.0667                 0      0        4        0:00:04      00:00:04.0000000
0.3667                 0      0        22       0:00:22      00:00:22.0000000
314.0833               5      14       4        5:14:04      05:14:04.0000000
625.8167               10     25       49       10:25:49     10:25:49.0000000
于 2017-05-26T14:27:58.730 回答
1

请注意,这将类似于 Greg 的回答,但我想对其进行解释和简化。

您有分钟数,因此将它们除以 60 并将其取底(删除小数点)给出小时数(不包括分钟数)。

如果您再次获取总分钟数,并删除(修改)小时数 - 这需要通过乘以 60 转换为分钟数 - 剩下的分钟数基本上只是在带走那么多组后找出剩下的时间六十年代:

SELECT FLOOR(course_access_minutes / 60) as Hours,
(FLOOR(course_access_minutes) % 60) as Minutes
FROM MyTable

如果您希望小数部分显示为小数部分(您希望秒以小数形式出现),请删除FLOOR.

如果您想要实数中的秒数,请保留FLOOR并使用 Greg 所拥有FLOOR((S.course_access_minutes - FLOOR(S.course_access_minutes)) * 60)的:秒数。不过要小心括号,因为您最终可能会不小心将十进制分钟数取底并得到 0,然后 0*60 为零:

FLOOR(
    (
        course_access_minutes - 
        FLOOR(course_access_minutes)
    ) * 60
) as Seconds
于 2020-02-25T18:31:52.160 回答
1

你可以这样FLOOR使用

DECLARE @SampleData AS TABLE
(
    Minutes numeric(18,4)
)

INSERT INTO @SampleData
VALUES
( 0.0500),
( 1.0500),
( 30.0500),
( 80.0500),
( 314.0833),
( 625.8167)

SELECT CONCAT(floor(sd.Minutes/60),':', CASE    WHEN sd.Minutes - floor(sd.Minutes/60)*60 < 1 THEN '0'
                                                ELSE FLOOR(sd.Minutes - floor(sd.Minutes/60)*60 )
                                        END) AS hours
FROM @SampleData sd

退货

hours
0:0
0:1
0:30
1:20
5:14
10:25
于 2017-05-26T13:47:19.273 回答