PostgreSQL中如何将时间/间隔时长转换为小数格式数值
PostgreSQL 时长字符串转小数小时实现方案
你之前使用Cast ( "Work duration" as integer)转换失败的核心原因是:1h30mn格式的结果包含h/mn非数字字符,PostgreSQL无法直接将这类混合字符串强转为数值类型。
以下提供两种可直接落地的实现方案:
方案1(优先推荐):跳过字符串拼接逻辑,直接计算小数时长
你原始的work_duration字段本身是分钟级数值,完全不需要先拼接成带单位的字符串再反向解析,直接计算即可得到目标结果,性能最高、逻辑最简洁:
-- 计算结果为1.5这类小数格式的小时时长,空值兜底逻辑和原代码一致 COALESCE(MAX(work_duration), 0) / 60.0 AS "Work duration"
注意:必须除以
60.0而非整数60,否则PostgreSQL会做整数除法截断小数部分(比如90分钟除以60会得到1而非1.5)。如果需要控制小数位数,可以套一层ROUND(字段, 保留位数)函数,比如保留2位小数就写ROUND(COALESCE(MAX(work_duration), 0) / 60.0, 2)。
方案2:基于已生成的xhxxmn格式字符串做解析转换
如果你的业务场景必须基于已经拼接完成的字符串字段做转换,可以通过字符串拆分+正则清洗提取数值后计算:
( -- 提取h之前的小时数值 COALESCE(NULLIF(split_part("Work duration", 'h', 1), '')::NUMERIC, 0) + -- 提取h之后、mn之前的分钟数值,除以60转成小时单位 COALESCE( NULLIF( regexp_replace(split_part("Work duration", 'h', 2), '[^0-9]', '', 'g'), '' )::NUMERIC / 60.0, 0 ) ) AS "Work duration decimal"
这段逻辑完全兼容你现有拼接逻辑的输出格式:不管是0h20mn、2h0mn、3h15mn这类边界格式都能正确解析为对应的小数时长。
注意:该方案依赖字符串格式完全匹配
[数字]h[数字]mn的规则,如果后续拼接格式调整,解析逻辑也需要同步修改,非必要不推荐使用。
内容的提问来源于stack exchange,提问作者Safa
相关产品推荐
相关产品推荐

