使用SQL Server 2008 R2将HH:MM:SS.MS转换为秒

时间:2014-12-01 17:48:24

标签: sql-server sql-server-2008 tsql datetime

我有一个数据库,其中时间存储为NVARCHAR(14)。当我查询特定用户的时间时,我看到的一个例子是00:08:45.68。

我想要做的是将此0小时,8分钟,45秒和68毫秒的值转换为526秒的值。向上舍入大于或等于50毫秒。

我还存储了没有捕获毫秒的值,例如: 98:40:12。有许多记录存储时间超过24小时,都有毫秒(97:18:59.32)和没有(98:40:12)。

我看到很多查询将秒转换为HH:MM:SS.MS,但没有反过来。我还看到许多包含日期的查询,但我没有随时间存储的日期。

希望我很清楚。

我尝试了以下内容:

(DATEPART(hh, trntime.time1) * 60 * 60) + (DATEPART(MI, trntime.time1) * 60) + DATEPART(s, trntime.time1) AS 'Calc_time1_Secs' 

但是我收到以下错误消息:

Msg 241, Level 16, State 1, Line 4
Conversion failed when converting date and/or time from character string.

3 个答案:

答案 0 :(得分:3)

任何小时值> 24不适用于TIME类型。除了第一个字段以外的所有字段都是固定长度,您可以:

;with T(f) as (select '97:18:59.32')

select 
    (LEFT(f, CHARINDEX(':', f) - 1)  * 60 * 60)
    + (SUBSTRING(f, CHARINDEX(':', f) + 1, 2) * 60)
    + SUBSTRING(f, CHARINDEX(':', f) + 4, 2)
    + CASE WHEN (SUBSTRING(f, CHARINDEX(':', f) + 7, LEN(f)) >= 50) 
             THEN 1 ELSE 0 END
from T

或者

select 
    (LEFT(f, CHARINDEX(':', f) - 1)  * 60 * 60) 
    + CAST(ROUND(DATEDIFF(MILLISECOND, 0, '00' 
    + (SUBSTRING(f, CHARINDEX(':', f), LEN(f)))) / 1000.0, 0) AS INT)
from T

答案 1 :(得分:0)

SQL Fiddle

MS SQL Server 2008架构设置

CREATE TABLE trntime
    ([time1] NVARCHAR(14))
;

INSERT INTO trntime
    ([time1])
VALUES
    ('00:08:45.68'),
    ('97:18:59.32'),
    ('97:18:59.52'),
    ('98:40:12')
;

查询1

SELECT (hour*60*60) + 
       (DATEPART(MI, minutes) * 60) + 
       DATEPART(S, minutes) + 
       ROUND(DATEPART(MS, minutes)/1000.0,0) AS 'Calc_time1_Secs'
FROM (SELECT LEFT(time1,2) AS 'hour', 
      '00' + RIGHT(time1,LEN(time1)-2) AS 'minutes'
      FROM trntime) AS Table1

<强> Results

| CALC_TIME1_SECS |
|-----------------|
|             526 |
|          350339 |
|          350340 |
|          355212 |

查询2

SELECT (LEFT(time1,2)*60*60) +
       ROUND(DATEDIFF(MS, 0, '00' + RIGHT(time1,LEN(time1)-2))/1000.0,0)
        AS 'Calc_time1_Secs'
FROM trntime

<强> Results

| CALC_TIME1_SECS |
|-----------------|
|             526 |
|          350339 |
|          350340 |
|          355212 |

答案 2 :(得分:0)

首先,如果时间不存在则加上0毫秒来标准化时间,然后用句号替换冒号并使用parsename(),因为这将总是有4个部分:

declare @t table (
    Id int identity(1,1) primary key,
    TimeSec nvarchar(14) not null
);

insert into @t (TimeSec)
values
    ('00:08:45'),
    ('14:18:59.79'),
    ('97:18:59.22'),
    ('98:40:12');


select sq.Id, sq.TimeSec, sq.PreparedTime, 
    cast(parsename(sq.PreparedTime, 4) as bigint) * 3600
    + cast(parsename(sq.PreparedTime, 3) as bigint) * 60
    + cast(parsename(sq.PreparedTime, 2) as bigint)
    + case 
        when cast(parsename(sq.PreparedTime, 1) as bigint) >= 50 
            then 1 
        else 0 
      end
as [TotalSec]
from (
    select t.*, 
            replace(
                        t.TimeSec + 
                        case 
                            when charindex(N'.', t.TimeSec) = 0 
                                then '.0' 
                            else '' 
                        end,
                        ':', 
                        '.'
                    ) as [PreparedTime]
    from @t t
) sq;