Cast在一个字段上工作,但不在其他字段上

时间:2016-10-17 18:48:13

标签: sql-server-2008 casting

我的表中有两个字段,Cycle和Idle,都是nvarchar(50),都包含时间。我试图使用TSQL根据特定的程序编号获得每个字段的总数。以下是数据的一个小例子。

Id      ProgramNo           Cycle       Idle
209702  3998_BOTH_OPPS.MPF  00:02:41    00:00:25
209703  472_7580_OPP1.MPF   00:02:08    00:01:44
209704  3998_BOTH_OPPS.MPF  00:00:27    00:00:11
209705  3998_BOTH_OPPS.MPF  00:00:00    00:00:00
209706  3998_BOTH_OPPS.MPF  00:00:01    00:01:40
209707  9491_OPP1.MPF       00:00:00    00:00:00
209708  9491_OPP1.MPF       00:00:01    00:00:04
209709  9491_OPP1.MPF       00:01:05    00:00:19

例如,获取ProgramNo 3998_BOTH_OPPS.MPF和9491_OPP1.MPF的总周期时间和空闲时间

这是我的查询...

SELECT
  ProgramNo,
  cast(dateadd(MILLISECOND, sum(datediff(MILLISECOND, 0, cast(Cycle AS DATETIME))), 0) AS TIME) AS CycleTime,
  cast(dateadd(MILLISECOND, sum(datediff(MILLISECOND, 0, cast(Idle AS DATETIME))), 0) AS TIME)  AS IdleTime
FROM Cycle
GROUP BY ProgramNo

它适用于CycleTime,但我收到IdleTime的错误:

  

“从字符串转换日期和/或时间时转换失败。”

有什么建议吗?先感谢您。

2 个答案:

答案 0 :(得分:1)

您需要找到与HH:MM:SS格式不匹配的值。

这是一种简单的方法:

select idle_time
from cycle
where idle_time not like '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]'

如果这不起作用,那么请查看组件:

where (idle_time like '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]' and
       (not (left(idle_time, 2) between '00' and '23') or
        not substring(idle_time, 4, 2) between '00' and '59') or
        not right(idle_time, 2) between '00' and '59')
       )

使用try_convert() SQL Server 2012+可以更轻松。

答案 1 :(得分:0)

根据您的上述评论,您可以像这样修复数据:

cast(dateadd(MILLISECOND, sum(datediff(MILLISECOND, 0, cast(right(Idle,8) AS DATETIME))), 0) AS TIME) as IdleTime

我们只看最右边的8个字符......所以如果没有#。在你的时间之前,它仍然可以工作

select right('3.18:15:05',8)
select right('18:15:05',8)