Snowflake предлагает очень мощные пользовательские табличные функции JavaScript , которые можно легко использовать здесь.
Вот код ...
Давайте сначала создадим данные
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);
Затем мы вводим табличную функцию, которая использует строки, содержащие col1
и col2
, и для каждой строки возвращает столбец MATCH
, содержащий 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
:
select * from t,
table(myfunc(col1, col2) over (partition by col3 order by row_number));
------+------+------+------------+-------+
COL1 | COL2 | COL3 | ROW_NUMBER | MATCH |
------+------+------+------------+-------+
b | c | s | 4 | FALSE |
a | d | s | 5 | TRUE |
a | d | r | 1 | FALSE |
a | c | r | 2 | FALSE |
b | d | r | 3 | FALSE |
a | d | r | 6 | TRUE |
------+------+------+------------+-------+
Если вам нужно, теперь вы можете просто отфильтровать по MATCH, и все готово.
Естественно, вы можете выражать произвольно сложную логику в такой функции, как эта.