在 Snowflake 中创建数组

Create an array in Snowflake

我想创建一个由两个时间戳构成的数组。 之后以此为范围求出第一个元素和第二个元素的区别

目标是找到工作时间(早上 9 点到晚上 17 点)内时间戳之间的时差。

正确的方法应该是什么?我可以创建数组然后找到时差吗?

例如在第一条记录中,由于 started_at 是在 17pm 之后,因此数组的第一个元素必须是 "2021-05-19 09:00:00".

示例数据:

WITH t1 AS (
SELECT 'A' AS id, '2021-05-18 18:30:00'::timestamp AS started_at, '2021-05-19 09:30:00'::timestamp AS ended_at UNION ALL
SELECT 'B' AS id, '2021-05-19 15:30:00'::timestamp AS started_at, '2021-05-20 13:00:00'::timestamp AS ended_at
    )
SELECT *
FROM t1

预期结果:

我们的想法是计算我们是否需要扩展范围,使用横向展平生成行并使用 case 语句计算时间戳。

演示:

WITH t1 AS (
SELECT 'A' AS id, '2021-05-18 18:30:00'::timestamp AS started_at, '2021-05-19 09:30:00'::timestamp AS ended_at UNION ALL
SELECT 'B' AS id, '2021-05-19 15:30:00'::timestamp AS started_at, '2021-05-20 13:00:00'::timestamp AS ended_at
    )
    
 select id, started_at, ended_at,
        array_construct(
         case when extend_before=1 and v.index=0 then started_at 
              when extend_before=1  then (dateadd(day,1,started_at::date)::string||' 09:00:00')::timestamp
              when extend_before=0 and started_at > (started_at::date::string||' 17:00:00')::timestamp then (dateadd(day,1,started_at::date)::string||' 09:00:00')::timestamp
             else started_at
         end, --as calculated_started_at,
         case when extend_before=1 and v.index=0 then  (started_at::date::string||' 17:00:00')::timestamp 
             else ended_at
         end --as calculated_ended_at
       ) as date_range,
       datediff(minute,date_range[0],date_range[1]) minutes_diff
 from
(
SELECT t1.*, case when started_at >= (started_at::date::string||' 17:00:00')::timestamp then 0 else 1 end as extend_before
FROM t1
) as s, lateral flatten(input=> split(space(s.extend_before),' '), outer => true) v

结果:

ID  STARTED_AT              ENDED_AT                 DATE_RANGE                                             MINUTES_DIFF
A   2021-05-18 18:30:00.000 2021-05-19 09:30:00.000 ["2021-05-19 09:00:00.000", "2021-05-19 09:30:00.000"]  30
B   2021-05-19 15:30:00.000 2021-05-20 13:00:00.000 ["2021-05-19 15:30:00.000", "2021-05-19 17:00:00.000"]  90
B   2021-05-19 15:30:00.000 2021-05-20 13:00:00.000 ["2021-05-20 09:00:00.000", "2021-05-20 13:00:00.000"]  240