我正在尝试将列数据从MM:SS转换为时间[HH:MM:SS.NNNNNNN],以便我可以聚合多维数据集/聚合维度中的字段。如[source]下面的照片所示,数据以MM:SS(varchar)的数据类型/格式登陆到我的数据库中。
我试图解析分钟和秒钟;将列转换为数据类型int;并写一个案例来计算小时数。
从此,我写了一个案例,将数据输入时间数据类型[Case Column photo]。但是,当我将新的计算字段转换为时间时,它会出现错误消息。
我将如何做到这一点?
SELECT CAST ( HRS AS VARCHAR(2) ) + ':' + CAST ( MN AS VARCHAR(2) ) + ':' + CAST (SEC AS VARCHAR(2)) + '.' + '0000000' AS TOI
FROM (
SELECT CASE
WHEN CAST ( PARSENAME ( REPLACE ( TOI, ':', '.'), 2 ) AS INT) > 60 AND CAST ( PARSENAME ( REPLACE ( TOI, ':', '.'), 2 ) AS INT) < 120 THEN '01'
WHEN CAST ( PARSENAME ( REPLACE ( TOI, ':', '.'), 2 ) AS INT) > 120 THEN '02'
WHEN CAST ( PARSENAME ( REPLACE ( TOI, ':', '.'), 2 ) AS INT) < 60 THEN '00'
ELSE '00'
END AS HRS
, CASE
WHEN CAST ( PARSENAME ( REPLACE ( TOI, ':', '.'), 2 ) AS INT) > 60 THEN CONCAT(0, PARSENAME ( REPLACE ( TOI, ':', '.'), 2 ) - 60)
WHEN CAST ( PARSENAME ( REPLACE ( TOI, ':', '.'), 2 ) AS INT) > 60 THEN PARSENAME ( REPLACE ( TOI, ':', '.'), 2 )
ELSE PARSENAME ( REPLACE ( TOI, ':', '.'), 2 )
END AS MN
, PARSENAME ( REPLACE ( TOI, ':', '.'), 1 ) AS SEC
FROM LAND_HOME_GOALIES
) S;
答案 0 :(得分:0)
我会将值转换为秒:
select convert(int, left(toi, 2)) * 60 + convert(int, right(toi, 2))
然后您可以总和为秒,然后再除以3600转换回小时数。或者使用dateadd()
转换为时间值为零时间。
答案 1 :(得分:0)
我认为将时态数据存储为叮咬是不明智的,它总会导致并发症。允许小时:分钟:该字符串中的秒数(修改为适合):
select
TOItime
from LAND_HOME_GOALIES
cross apply (select replace(TOI,':','.')) ca1 (xTOI)
cross apply (
select coalesce(try_cast(parsename(ca1.xTOI,3) as int),0) * 3600
+ coalesce(try_cast(parsename(ca1.xTOI,2) as int),0) * 60
+ coalesce(try_cast(parsename(ca1.xTOI,1) as int),0)
) ca2 (secs)
cross apply (select try_cast(dateadd(second,ca2.secs,0) as time)) ca3 (TOItime)
我假设您可以使用try_cast,如果不使用强制转换,但转换为int时可能会出错。
修改
为了演示以下SQL Fiddle将显示它将原始字符串转换为时间而对行数没有任何影响:
MS SQL Server 2014架构设置:
CREATE TABLE LAND_HOME_GOALIES
([TOI] varchar(5))
;
INSERT INTO LAND_HOME_GOALIES
([TOI])
VALUES
('40:36'),
('19:24'),
('61:15'),
('60:00'),
('58.47'),
('59:54'),
('64:49')
;
查询1 :
select
TOI, ca1.xTOI, ca2.secs, ca3.TOItime
from LAND_HOME_GOALIES
cross apply (select replace(TOI,':','.')) ca1 (xTOI)
cross apply (
select coalesce(try_cast(parsename(ca1.xTOI,3) as int),0) * 3600
+ coalesce(try_cast(parsename(ca1.xTOI,2) as int),0) * 60
+ coalesce(try_cast(parsename(ca1.xTOI,1) as int),0)
) ca2 (secs)
cross apply (select try_cast(dateadd(second,ca2.secs,0) as time)) ca3 (TOItime)
<强> Results 强>:
| TOI | xTOI | secs | TOItime |
|-------|-------|------|------------------|
| 40:36 | 40.36 | 2436 | 00:40:36.0000000 |
| 19:24 | 19.24 | 1164 | 00:19:24.0000000 |
| 61:15 | 61.15 | 3675 | 01:01:15.0000000 |
| 60:00 | 60.00 | 3600 | 01:00:00.0000000 |
| 58.47 | 58.47 | 3527 | 00:58:47.0000000 |
| 59:54 | 59.54 | 3594 | 00:59:54.0000000 |
| 64:49 | 64.49 | 3889 | 01:04:49.0000000 |
答案 2 :(得分:0)
在现实生活中,'61:15
'被认为不是有效的MM:SS
数据,就像你说的那样。但是如果它以某种方式确实存在,
declare @table table(TOI varchar(10))
insert into @table values ('241:15')
,('61:15'),('40:36')
select TOI as OLdTOI,right(('00'+ cast(([Min]/60) as varchar)),2)
+':'+right('00'+cast([Min]-([Min]/60)*60 as varchar) , 2)
+':'+ right('00'+Sec,2) NewTOI
from
(
select TOI, substring(TOI,0,charindex(':',TOI)) [Min]
,substring(TOI,charindex(':',TOI)+1,len(TOI)) Sec
from @table
)t4