如何计算超过正常varchar值的时间值(存储为varchars)?

时间:2018-12-19 12:29:00

标签: sql-server tsql datetime sum varchar

我正在处理的脚本有麻烦。我所拥有的是数据库中有关应用程序何时关闭,何时重新打开以及应用程序关闭总时间的值。使用我现在使用的脚本,有时TotalDownTime超过24小时。这是有意的,我想保持这种方式。但是,我还希望能够根据关闭这些应用程序的原因将所有TotalDownTimes总计为一个值。如何最好地做到这一点?

以下是我正在使用的一些示例:

Reason                  Shutdowndate            StartupDate             TotalDownTime
Scheduled Maintenance   2018-12-10 09:31:47.317 2018-12-10 11:31:47.317 02:00:00:000
Scheduled Maintenance   2018-12-10 09:38:00.373 2018-12-10 09:45:38.613 00:07:38:240
Scheduled Maintenance   2018-12-10 10:43:01.000 2018-12-18 08:22:02.873 21:39:01:873
Scheduled Maintenance   2018-12-16 00:01:07.697 2018-12-16 12:00:10.953 11:59:03:257
Scheduled Maintenance   2018-12-01 00:00:00.000 2018-12-18 13:54:16.500 421:54:16:000
Scheduled Maintenance   2018-12-06 00:00:00.000 2018-12-18 08:41:45.007 296:41:45

这是我用来分配TotalDownTime值的东西:

Update ProductionShutdownRecord 
set TotalDownTime = CAST(DATEDIFF(HOUR, [ShutdownDate], [Startupdate]) AS VARCHAR)
     + RIGHT(CONVERT(CHAR(8),DATEADD(SECOND,DATEDIFF(SECOND, [ShutdownDate], [Startupdate]),0),114),6)
where shutdownId = 18

这是我要尝试用来求和的值,我得到的错误是“将char数据类型转换为datetime数据类型导致日期时间值超出范围。 “:

select convert(char(8),dateadd(second,SUM ( DATEPART(hh,(convert(datetime,TotalDownTime,1))) * 3600 +
DATEPART(mi, (convert(datetime,TotalDownTime,1))) * 60 + DATEPART(ss,(convert(datetime,TotalDownTime,1)))),0),108)
FROM ProductionShutdownRecord
where Reason like 'Scheduled Maintenance%'
and ShutdownDate >= '01/01/2018'
and ShutdownDate <= '01/01/2019'
and startupdate is not null

感谢您的帮助,谢谢!

3 个答案:

答案 0 :(得分:1)

表中的字段是什么数据类型?

我会将TotalDownTime视为INT或BIGINT,并且将差异存储为所需的最低时间部分的倍数。例如DATEDIFF(秒,Startupdate,Shutdowndate)或DATEDIFF_BIG(秒,Startupdate,Shutdowndate)。那么SUM是微不足道的。

然后变成输出格式问题,以任何想要的字符串格式获取它,这也应该很简单-如果您需要直接在数据库中使用的格式,请在表中添加一个计算字段。

答案 1 :(得分:0)

您可以以秒为单位计算和汇总所有内容,然后转换为小时,分钟和秒:

SELECT
    tot_downtime_sec / 3600 hh,
    tot_downtime_sec % 3600 / 60 mm,
    tot_downtime_sec % 60 ss
FROM (
    SELECT SUM(DATEDIFF(SECOND, Shutdowndate, StartupDate)) AS tot_downtime_sec
    FROM @t
) x

将三个值连接起来具有922:21:43很简单(使用FORMAT函数)。您还可以将以上内容扩展为将922小时转换为38天10小时。

答案 2 :(得分:0)

以下是一种方法,使用FORMAT来简化非标准时间格式的格式化:

WITH downtime AS (
    SELECT
      Reason
    , Shutdowndate
    , StartupDate
    , DATEADD(millisecond, DATEDIFF(millisecond, Shutdowndate, StartupDate), '') AS DownTime
    FROM dbo.ApplicationDowntime
)
SELECT
      Reason
    , Shutdowndate
    , StartupDate
    , FORMAT(((DATEPART(day, DownTime) - 1) * 24) + DATEPART(hour, DownTime), '00:')
        + FORMAT(DownTime, 'mm:ss:fff') AS TotalDownTime
FROM downtime;

请注意,这将为示例结果的第三行返回189:39:01:873

+-----------------------+-------------------------+-------------------------+---------------+
|        Reason         |      Shutdowndate       |       StartupDate       | TotalDownTime |
+-----------------------+-------------------------+-------------------------+---------------+
| Scheduled Maintenance | 2018-12-10 09:31:47.317 | 2018-12-10 11:31:47.317 | 02:00:00:000  |
| Scheduled Maintenance | 2018-12-10 09:38:00.373 | 2018-12-10 09:45:38.613 | 00:07:38:240  |
| Scheduled Maintenance | 2018-12-10 10:43:01.000 | 2018-12-18 08:22:02.873 | 189:39:01:873 |
| Scheduled Maintenance | 2018-12-16 00:01:07.697 | 2018-12-16 12:00:10.953 | 11:59:03:257  |
| Scheduled Maintenance | 2018-12-01 00:00:00.000 | 2018-12-18 13:54:16.500 | 421:54:16:500 |
| Scheduled Maintenance | 2018-12-06 00:00:00.000 | 2018-12-18 08:41:45.007 | 296:41:45:007 |
+-----------------------+-------------------------+-------------------------+---------------+