我有一个数据库,其中时间存储为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.
答案 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)
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;