Sql server 如何将超过正常varchar值的时间值(存储为varchar)相加?

Sql server 如何将超过正常varchar值的时间值(存储为varchar)相加?,sql-server,tsql,datetime,sum,varchar,Sql Server,Tsql,Datetime,Sum,Varchar,我正在编写的脚本有问题。我拥有的是数据库中的值,用于应用程序关闭、重新打开以及应用程序关闭的总持续时间。对于我现在使用的脚本,有时总停机时间超过24小时。这是故意的,我想保持这种方式。但是,我也希望能够根据这些应用程序关闭的原因,将所有TotalDowntime相加为一个值。如何才能最好地做到这一点 以下是我正在使用的一些示例: Reason Shutdowndate StartupDate TotalDownTim

我正在编写的脚本有问题。我拥有的是数据库中的值,用于应用程序关闭、重新打开以及应用程序关闭的总持续时间。对于我现在使用的脚本,有时总停机时间超过24小时。这是故意的,我想保持这种方式。但是,我也希望能够根据这些应用程序关闭的原因,将所有TotalDowntime相加为一个值。如何才能最好地做到这一点

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

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数据类型导致datetime值超出范围。 “:

选择convert(char(8)、dateadd(second、SUM(DATEPART(hh),(convert(datetime,totaldown,1)))*3600+
DATEPART(mi,(convert(datetime,totaldown,1)))*60+DATEPART(ss,(convert(datetime,totaldown,1))),0),108)
从ProductionShutdown记录
原因何在,如“定期维护%”
和关闭日期>='2018年1月1日'

下面的ShutdownDate是一种方法,它使用
格式
来简化非标准时间格式的格式设置:

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 |
+-----------------------+-------------------------+-------------------------+---------------+

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

我将TotalDownTime视为INT或BIGINT,其差值存储在所需最低时间部分的倍数中。e、 g.DATEDIFF(第二个,Startupdate,Shutdowndate)或DATEDIFF_BIG(第二个,Startupdate,Shutdowndate)。那么总和是微不足道的


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

而不是使用
VARCHAR
作为
TotalDownTime
列,为什么不使用
INT
这是
DATEDIFF
返回的类型?然后,您可以使用
second
而不是
hour
进行
DATEDIFF
计算,只需在显示层中将结果转换为人类可读的格式即可。这也会使求和变得容易得多。我使用了varchar,因为我认为它更容易存储为实际的时间值。反正当时哈哈。我当然可以尝试将其作为INT。您可以为增量时间(以秒为单位)和增量时间的格式化版本添加计算列。存储一个从其他列值派生的值是对表的非规范化:您将有三个可以独立更改的相关值。最终,我认为将其更改为int是最好的解决方案。正如您所说,如果我需要一个格式化的值,我总是可以添加另一列。谢谢大家的回答!
+-----------------------+-------------------------+-------------------------+---------------+
|        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 |
+-----------------------+-------------------------+-------------------------+---------------+