将持续时间格式 P0DT0H0M0S(ISO 8601 持续时间格式)转换为小时

Convert duration format P0DT0H0M0S (ISO 8601 Duration Format) to hours

我正在寻找一种将“ISO 8601 持续时间格式”(P0DT0H0M0S) 转换为小时的简便方法。

到目前为止我已经想到了这个:

# Example in BigQuery
SELECT
    24 * CAST(SPLIT(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('P1DT2H3M44S', 'P', ''), 'DT', '-'), 'H', '-'), 'M', '-'), 'S', ''), '-')[OFFSET(0)] AS INT64)
    + CAST(SPLIT(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('P1DT2H3M44S', 'P', ''), 'DT', '-'), 'H', '-'), 'M', '-'), 'S', ''), '-')[OFFSET(1)] AS INT64)
    + (1/60) * CAST(SPLIT(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('P1DT2H3M44S', 'P', ''), 'DT', '-'), 'H', '-'), 'M', '-'), 'S', ''), '-')[OFFSET(2)] AS INT64)
    + (1/3600) * CAST(SPLIT(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('P1DT2H3M44S', 'P', ''), 'DT', '-'), 'H', '-'), 'M', '-'), 'S', ''), '-')[OFFSET(3)] AS INT64) AS HOURS

如您所见,我的方法是拆分数字并乘以 24、1、1/60、1/3600 得到小时数。我可以减少代码量吗?

Sample data and desired result
Input: 'P1DT2H3M44S' (1 day, 2 hours, 3 minutes, 44 seconds)
Desired output: 26.06222222222222 (this is hours)

尝试以下选项

select *,    
  (select sum(cast(val as int64) * weight)
   from unnest(regexp_extract_all(col, r'\d+')) val with offset
   join unnest([24, 1, 1/60, 1/3600]) weight with offset 
   using(offset)
  ) as hours
from `project.dataset.table`     

如果应用于您问题中的示例数据 - 输出是

以上假定所有部分(天、小时、分钟、秒)都存在,即使它们为零

如果不是这种情况 - 我怀疑是,但不确定 - 需要对上述解决方案进行轻微调整。让我知道

此选项比原始代码更简洁,但仍然易于理解和修改。

SELECT
    'P0DT5H47M0S' AS iso_8601_duration,
    24 * CAST(REGEXP_EXTRACT('P0DT5H47M0S', '[0-9]+', 1, 1) AS INT64)
    + 1 * CAST(REGEXP_EXTRACT('P0DT5H47M0S', '[0-9]+', 1, 2) AS INT64)
    + (1/60) * CAST(REGEXP_EXTRACT('P0DT5H47M0S', '[0-9]+', 1, 3) AS INT64)
    + (1/3600) * CAST(REGEXP_EXTRACT('P0DT5H47M0S', '[0-9]+', 1, 4) AS INT64) AS Hours