在SQL

时间:2017-07-07 19:18:06

标签: sql sql-server sql-server-2008

我正在尝试从多行添加时间,当它们加起来超过几小时时,我找不到正确的结果。希望脚本TotalTime允许HH超过24。不必是datetime数据类型。

StartTimeFinishTime是varchar(8)数据类型。

这里是TotalTime小于24小时且结果正确的代码和输出

SELECT Codes = (DeptCode + '-' +  OpCode)
,TotalTime = convert(time(0),dateadd(second,sum(datediff(second,StartTime,FinishTime)),0)) 
,Units = SUM(Units)
,UPH = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60  as decimal(10,0))
,'Goal%' = (convert(varchar,cast((isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60)/5101*100 as decimal(10,0))) + '%') 
FROM PTW.dbo.TimeLog 
WHERE DeptCode = 'HP' AND OpCode = 'FC'
GROUP BY DeptCode, OpCode

结果是正确的

Codes   TotalTime   Units   UPH   Goal%
HP-FC   12:37:00    47200   3741    73%

以下是实际细分证明

ID#     Codes   TotalTime   Units   UPH     Goal%   AssociateName
---     -----   ---------   -----   ---     -----   -------------
2409193 HP-FC   00:21:00    2161    6174    121%    NAME
2507191 HP-FC   00:23:00    2000    5217    102%    NAME
90290   HP-FC   00:20:00    1704    5112    100%    NAME
31676   HP-FC   02:35:00    11234   4349    85%     NAME
2372437 HP-FC   01:50:00    7884    4300    84%     NAME
2378337 HP-FC   07:08:00    22217   3115    61%     NAME

因此,当我在一个包含更多数据行的较大表上尝试此操作时,这就是我得到的。输出将显示TotalTime作为不正确的时间。

SELECT Codes = (DeptCode + '-' +  OpCode)
,TotalTime = convert(time(0),dateadd(second,sum(datediff(second,StartTime,FinishTime)),0))     
,Units = SUM(Units)
,UPH = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60  as decimal(10,0))
,'Goal%' = (convert(varchar,cast((isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60)/1552*100 as decimal(10,0))) + '%') 
FROM PTW.dbo.TimeLog
WHERE DeptCode = 'HS' AND OpCode = 'HY'
GROUP BY DeptCode, OpCode

查询结果如下。这不可能是真正的时间。

Codes   TotalTime   Units   UPH     Goal%
HS-HY   14:07:00    69204   1114    72%

细分显示TotalTime应该超过14:07:00

ID#     Codes   TotalTime   Units   UPH     Goal%   AssociateName
---     -----   ---------   -----   ---     -----   -------------
2377    HS-HY   11:25:00    20891   1830    118%    NAME
3476    HS-HY   04:50:00    6978    1444    93%     NAME
43864   HS-HY   12:20:00    17628   1429    92%     NAME
2372127 HS-HY   03:20:00    4748    1424    92%     NAME
2372129 HS-HY   07:00:00    9158    1308    84%     NAME
2422946 HS-HY   00:47:00    949     1211    78%     NAME
21437   HS-HY   06:02:00    6530    1082    70%     NAME
2372090 HS-HY   11:00:00    2322    211     14%     NAME
63448   HS-HY   03:43:00    0       0       0%      NAME
2372061 HS-HY   01:40:00    0       0       0%      NAME

3 个答案:

答案 0 :(得分:2)

对于可能超过24小时的间隔,您需要连接一组计算每个部分的表达式,如下所示:

select 
    Codes     = (DeptCode + '-' + OpCode)
  , TotalTime = right('0' + convert(varchar(9),(sum(datediff(second,StartTime,FinishTime)) / 3600 )),2) + ':' 
              + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) / 60) % 60 ),2) + ':' 
              + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) % 60 )),2)
  , Units     = sum(Units)
  , UPH       = cast(isnull(sum(Units) / nullif(sum(datediff(minute, StartTime, FinishTime)) * 1.0, 0), 0.0) * 60 as decimal(10, 0))
  , [Goal%]   = (convert(varchar, cast((isnull(sum(Units) / nullif(sum(datediff(minute, StartTime, FinishTime)) * 1.0, 0), 0.0) * 60) / 5101 * 100 as decimal(10, 0))) + '%')
from ptw.dbo.TimeLog
where DeptCode = 'HP'
  and OpCode = 'FC'
group by 
    DeptCode
  , OpCode

此外,不应将字符串文字用于别名,对于不符合常规标识符规则的别名,请将它们用方括号括起来而不是单引号。

答案 1 :(得分:1)

我认为您的问题是时间数据类型不足以容纳超过24小时的值。

您需要创建其他类型的变量来跟踪小时,分钟,秒等 - 尽可能准确地跟踪。

https://docs.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql

答案 2 :(得分:1)

那是因为您要将总和转换为time数据类型,这意味着"日期时间的时间部分"。因此,总共不会超过24个,因为即使在军事时代,也没有25点的时间。

要获得正确的总数,一种方法是构建varchar数据类型而不是time类型。您需要通过将秒数除以60和60 * 60来生成varchar字符串,以生成分钟和小时部分。