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)
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)