Snowflake中VARCHAR类型DURATION字段转数值型并归一化为分钟
Snowflake中DURATION字段转分钟数的解决方案
直接上可用的SQL逻辑,能处理所有有效格式,同时兼容空白、无效文本等异常情况:
SELECT DURATION, COALESCE( -- 天数转分钟:1天=1440分钟 TRY_TO_NUMBER(REGEXP_SUBSTR(DURATION, '\\d+', 1, 1, 'i', 1)) * 1440 -- 小时转分钟:1小时=60分钟,不存在则补0 + COALESCE(TRY_TO_NUMBER(REGEXP_SUBSTR(DURATION, '\\d+', 1, 2, 'i', 1)) * 60, 0) -- 直接加分钟数,不存在则补0 + COALESCE(TRY_TO_NUMBER(REGEXP_SUBSTR(DURATION, '\\d+', 1, 3, 'i', 1)), 0) -- 秒转分钟:1分钟=60秒,不存在则补0 + COALESCE(TRY_TO_NUMBER(REGEXP_SUBSTR(DURATION, '\\d+', 1, 4, 'i', 1)) / 60, 0), 0) AS TOTAL_MINUTES FROM YOUR_TABLE;
关键逻辑说明
- 正则适配性优化:用
REGEXP_SUBSTR的'i'参数忽略大小写,兼容Day/Days/Hour/Hours这类大小写混合或单复数的单位;第6个参数指定捕获组,直接提取数字部分,避免带单位的字符串导致转换失败。 - 无效值容错:
TRY_TO_NUMBER会把非数字的无效内容转为NULL,再通过COALESCE将NULL替换为0,确保最终结果不会出现空值。 - 多单位兼容:不管是单一单位(如
3 hours)还是多单位组合(如1 day 3 hours 35 minutes),正则会按顺序捕获对应数字,不存在的单位自动补0,不影响累加结果。
你之前结果全0/NULL的常见原因
- 正则未处理大小写/单复数:如果没加
'i'参数,会匹配不到Hours或Days这类大写开头的单位,导致提取失败返回NULL。 - 未单独提取数字:若直接匹配带单位的字符串(比如
3 hours),TRY_TO_NUMBER转换带字母的内容会返回NULL。 - CASE逻辑覆盖不全:如果CASE语句没考虑多单位组合的情况,会导致部分有效数据被判定为无效,返回0或NULL。
测试用例验证
| DURATION | TOTAL_MINUTES |
|---|---|
| 7 Hours 13 Minutes | 433 |
| 1 day 3 hours 35 minutes | 1655 |
| 30 seconds | 0.5 |
| Days | 0 |
| (空白) | 0 |
| 2 Days 5 Minutes | 2885 |
内容的提问来源于stack exchange,提问作者GoonerDude
相关产品推荐
相关产品推荐

