第一行匹配条件,第一行匹配其他条件之后

时间:2018-11-05 08:25:25

标签: window-functions snowflake-datawarehouse

如何找到与条件匹配的第一行,并在第一行之后与其他条件匹配?我可以很容易地通过联接来做到这一点,但希望避免联接(因此大概使用窗口函数)。我正在使用Snowflake(但是,如果您知道另一种方言的答案,我可以尝试将其翻译)。没有加入我就无法找到一种方法。

为清楚起见,假设我的数据是

create table t (col1 varchar, col2 varchar, col3 varchar, row_number int) as
      select 'a', 'd' ,'r', 1
union select 'a', 'c', 'r', 2
union select 'b', 'd', 'r', 3
union select 'b', 'c', 's', 4
union select 'a', 'd', 's', 5
union select 'a', 'd', 'r', 6

在带有col3='r'的行中,第一个带有col2='c'的行是2,此后的第一个 带有col1='a'的行是6。我希望选择行根据这些条件得出6。

1 个答案:

答案 0 :(得分:1)

雪花提供了非常强大的JavaScript user-defined table functions,可以在此处轻松使用。

这是代码...

首先创建数据

create or replace table t (col1 varchar, col2 varchar, col3 varchar, row_number int)
as select * from values
        ('a', 'd' ,'r', 1),
        ('a', 'c', 'r', 2),
        ('b', 'd', 'r', 3),
        ('b', 'c', 's', 4),
        ('a', 'd', 's', 5),
        ('a', 'd', 'r', 6);

然后,我们引入一个表函数,该函数使用包含col1col2的行,并为每行返回一个包含MATCH的{​​{1}}列,具体取决于它是否与谓词匹配< / p>

true/false

然后我们使用它,按CREATE OR REPLACE FUNCTION myfunc ( col1 varchar, col2 varchar) RETURNS TABLE (MATCH boolean) LANGUAGE JAVASCRIPT AS $$ { seen: false, produced: false, processRow: function (row, rowWriter, context) { let match = false; if (!this.seen && row.COL2 == "c") { this.seen = true; } else if (this.seen && !this.produced && row.COL1 == "a") { this.produced = true; match = true; } rowWriter.writeRow({MATCH: match}); }, initialize: function (argumentInfo, context) { this.seen = this.produced = false; } } $$; 对数据进行分区,并确保行沿col3被使用:

row_number

如果需要,您现在只需在MATCH上进行过滤就可以了。

自然地,您可以在这样的函数中表达任意复杂的逻辑。