Snowflake 的时差替代 Postgres INTERVAL

Snowflake's time difference alternative to Postgres INTERVAL

我有以毫秒为单位的 UNIX 持续时间,需要将其转换为人类可读的格式。在 Postgres 中可以使用 INTERVAL 类型,但如何在 Snowflake 中完成?挑战在于其中一些值可能超过 24 小时。我已经在 Snowflake forum 上检查了类似问题的解决方案(对 ms 进行了调整)。但是不支持时间>24h

示例数据:

7200000 -- 2h
28800000 --8h
1800000 -- 30min
252000000 -- 70h
86400000 -- 24h
3593314 -- 59min 53sec

以便所需的输出看起来像:

02:00:00
08:00:00
00:30:00
70:00:00
24:00:00
00:59:53

可能是我搜索不好,但是至今没能找到解决这个问题的方法。

适用于 Postgres 的解决方案SELECT time_unix::bigint * INTERVAL '1 ms'

select *
    ,floor(ms/3600000) as hh
    ,floor((ms%3600000)/60000) as mm
    ,floor((ms%60000)/1000) as ss
    ,nullifzero(hh) as a1
    ,nullifzero(mm) as a2
    ,nullifzero(ss) as a3
    ,trim(nvl(a1||'h ','') || nvl(a2||'m ','') || nvl(a3||'s','')) as r 
from values
    (7200000, '2h'),
    (28800000 , '8h'),
    (1800000, '30min'),
    (252000000, '70h'),
    (86400000, '24h'),
    (3593314, '59min 53sec')
    t(ms, wanted)

给出:

MS WANTED HH MM SS A1 A2 A3 R
7,200,000 2h 2 0 0 2 2h
28,800,000 8h 8 0 0 8 8h
1,800,000 30min 0 30 0 30 30m
252,000,000 70h 70 0 0 70 70h
86,400,000 24h 24 0 0 24 24h
3,593,314 59min 53sec 0 59 53 59 53 59m 53s

因此:

select *
    ,trim(nvl(nullifzero(floor(ms/3600000))||'h ','') || nvl(nullifzero(floor((ms%3600000)/60000))||'m ','') || nvl(nullifzero(floor((ms%60000)/1000))||'s','')) as r 
from values
    (7200000, '2h'),
    (28800000 , '8h'),
    (1800000, '30min'),
    (252000000, '70h'),
    (86400000, '24h'),
    (3593314, '59min 53sec')
    t(ms, wanted)

给出:

MS WANTED R
7,200,000 2h 2h
28,800,000 8h 8h
1,800,000 30min 30m
252,000,000 70h 70h
86,400,000 24h 24h
3,593,314 59min 53sec 59m 53s

或者我可以阅读:

select *
    ,trim(nvl(nullifzero(floor(ms/3600000))||'h ','') || nvl(nullifzero(floor((ms%3600000)/60000))||'m ','') || nvl(nullifzero(floor((ms%60000)/1000))||'s','')) as r 
    ,lpad(floor(ms/3600000), 2, 0) || ':' || lpad(floor((ms%3600000)/60000), 2, 0) || ':' || lpad(floor((ms%60000)/1000), 2, 0) as r2
from values
    (7200000, '2h'),
    (28800000 , '8h'),
    (1800000, '30min'),
    (252000000, '70h'),
    (86400000, '24h'),
    (3593314, '59min 53sec')
    t(ms, wanted)
MS WANTED R R2
7,200,000 2h 2h 02:00:00
28,800,000 8h 8h 08:00:00
1,800,000 30min 30m 00:30:00
252,000,000 70h 70h 70:00:00
86,400,000 24h 24h 24:00:00
3,593,314 59min 53sec 59m 53s 00:59:53

想知道是否有人可以想出更糟糕的解决方案:)

create or replace function pginterval( TIME number )
returns varchar
language sql
as
$$
select  LPAD( (extract( day from to_timestamp( TIME, 3 )) - 1 ) * 24 + extract( hour from  to_timestamp( TIME, 3 )), 2, '0' )
|| ':' || right( to_timestamp( TIME, 3 )::time, 5 )
$$;

select pginterval( x )
from values 
(7200000),
(28800000),
(1800000),
(252000000),
(86400000),
(3593314) tmp (x);
PGINTERVAL( X )
02:00:00
08:00:00
00:30:00
70:00:00
24:00:00
00:59:53