如何将FLOAT类型时间值转换为TIME类型列?
FLOAT类型时间数据转TIME字段的SQL实现
需求背景
需要将存储为FLOAT类型的20年历史时间数据转换为TIME字段,现有测试表结构及测试数据如下:
CREATE TABLE #T ( TVALUE FLOAT(8), EXPECTED_TVALUE TIME ); INSERT INTO #T (TVALUE, EXPECTED_TVALUE) VALUES (0, null), (9.474, '09:47:40'), (11.3015, '11:30:15'), (1.0, '01:00:00'), (13, '13:00:00');
尝试过的错误转换语句
以下几种方式均无法得到正确结果:
SELECT TVALUE, EXPECTED_TVALUE, FORMAT(FLOOR(TVALUE) * 10000 + (TVALUE - FLOOR(TVALUE)) * 60 + (TVALUE - FLOOR(TVALUE)) * 60, '00:00:00') AS TMP_TVALUE FROM #T SELECT TVALUE, EXPECTED_TVALUE, CAST(CONVERT(VARCHAR,DATEADD(SECOND, TVALUE * 3600, 0),108) AS TIME) AS TMP_TVALUE FROM #T SELECT TVALUE, EXPECTED_TVALUE, FORMAT(TVALUE, '00:00:00') AS TMP_TVALUE FROM #T
正确的单语句转换方案
无需使用函数或存储过程,可通过拆分FLOAT值的小时、分钟、秒部分实现转换,语句如下:
SELECT TVALUE, EXPECTED_TVALUE, CASE WHEN TVALUE = 0 THEN NULL ELSE CAST( CONCAT( RIGHT('0' + CAST(FLOOR(TVALUE) AS VARCHAR(2)), 2), ':', RIGHT('0' + CAST(FLOOR((TVALUE - FLOOR(TVALUE)) * 60) AS VARCHAR(2)), 2), ':', RIGHT('0' + CAST(ROUND((TVALUE - FLOOR(TVALUE)) * 3600 % 60, 0) AS VARCHAR(2)), 2) ) AS TIME END AS TMP_TVALUE FROM #T
逻辑说明
FLOOR(TVALUE)提取整数部分作为小时,补前导零保证两位格式- 小数部分乘以60后取整得到分钟,同样补前导零
- 小数部分乘以3600后取余60,四舍五入得到秒数,补前导零
- 拼接成
HH:MM:SS格式字符串后转换为TIME类型 - 针对TVALUE为0的场景返回NULL,匹配预期结果
内容的提问来源于stack exchange,提问作者JStefan
相关产品推荐
相关产品推荐

