计算雪花中的警报洪水

Dan*_*any 5 sql snowflake-schema snowflake-cloud-data-platform

我正在尝试在雪花中进行警报洪水计算。我使用雪花窗函数创建了以下数据集。因此,如果该值大于或等于 3,则警报洪水将开始,对于下一个 0 值,它将结束。所以在下面的例子中,警报洪水从“9:51”开始,在“9:54”结束,持续了 3 分钟。下一次洪水从“9:57”开始,在“10:02”结束,即5 分钟。仅供参考,9:59 的值是 3,但是由于洪水已经开始,我们不必考虑它。下一次洪水是在 10:03 但没有 0 值,所以我们必须考虑边缘值 10:06。所以洪水中的总时间是 3+5+4=12 分钟。

   DateTime    Value
3/10/2020 9:50  1
3/10/2020 9:51  3
3/10/2020 9:52  1
3/10/2020 9:53  2
3/10/2020 9:54  0
3/10/2020 9:55  0
3/10/2020 9:56  1
3/10/2020 9:57  3
3/10/2020 9:58  2
3/10/2020 9:59  3
3/10/2020 10:00 2
3/10/2020 10:01 2
3/10/2020 10:02 0
3/10/2020 10:03 3
3/10/2020 10:04 1
3/10/2020 10:05 1
3/10/2020 10:06 1
Run Code Online (Sandbox Code Playgroud)

所以,简而言之,我期待低于输出

在此处输入图片说明

我在 SQL 下尝试过,但它没有给我正确的输出,它在第二次洪水时间失败(因为在下一个 0 之前再次有值 3)

select t.*,
       (case when value >= 3
             then datediff(minute,
                           datetime,
                           min(case when value = 0 then datetime end) over (order by datetime desc)
                          )
        end) as diff_minutes
from t;
Run Code Online (Sandbox Code Playgroud)

wal*_*nte 1

JavaScript udf 版本:

select d, v, iff(3<=v and 1=row_number() over (partition by N order by d),
    count(*) over (partition by N), null) trig_duration
from t, lateral flood_count(t.v::float) 
order by d;
Run Code Online (Sandbox Code Playgroud)

其中flood_count()定义为:

create or replace function flood_count(V float) 
returns table (N float)
language javascript AS
$${

  initialize: function() { 
    this.n = 0 
    this.flood = false
  },

  processRow: function(row, rowWriter) { 
    if (3<=row.V && !this.flood) {
        this.flood = true
        this.n++
    }
    else if (0==row.V) this.flood=false
    rowWriter.writeRow({ N: this.flood ? this.n : null })  
  },

}$$;
Run Code Online (Sandbox Code Playgroud)

假设这个输入:

create or replace table t as
select to_timestamp(d, 'mm/dd/yyyy hh:mi') d, v 
from values
    ('3/10/2020 9:50',  1),
    ('3/10/2020 9:51',  3),
    ('3/10/2020 9:52',  1),
    ('3/10/2020 9:53',  2),
    ('3/10/2020 9:54',  0),
    ('3/10/2020 9:55',  0),
    ('3/10/2020 9:56',  1),
    ('3/10/2020 9:57',  3),
    ('3/10/2020 9:58',  2),
    ('3/10/2020 9:59',  3),
    ('3/10/2020 10:00', 2),
    ('3/10/2020 10:01', 2),
    ('3/10/2020 10:02', 0),
    ('3/10/2020 10:03', 3),
    ('3/10/2020 10:04', 1),
    ('3/10/2020 10:05', 1),
    ('3/10/2020 10:06', 1)
    t(d,v)
;
Run Code Online (Sandbox Code Playgroud)