雪花中的 Match_Recognize 没有返回我认为它应该返回的内容

时间:2021-04-26 03:46:58

标签: snowflake-cloud-data-platform match-recognize

我确定我不理解这一点,但这被定义为

<块引用>

PATTERN:指定模式以匹配 PATTERN ( ) 模式定义表示匹配的有效行序列。这 模式被定义为一个正则表达式(regex),并且是从 符号、运算符和量词。

一个例子是:

<块引用>

例如,假设代码 S1 定义为 stock_price < 55, 并且符号 S2 被定义为股票价格 > 55。以下模式 指定一系列行,其中股票价格从 小于 55 到大于 55:

模式(S1 S2)

所以如果我这样做

create or replace table names (id int, name varchar (500), groupid int); 

insert into names
           select 1, 'andrew', 1
           union
           select 2, 'andrew2', 1
           union
           select 3, '3andrew', 1

然后我做

select * from names
match_recognize(
partition by groupid order by id
measures
  classifier() as "classifier"
  all rows per match  
pattern (test test2)  
define test as startswith(name, 'and'),
  test2 as endswith(name, 'rew') 
 ) t
;        

为什么我没有得到 'andrew' 作为记录回报?如果我在模式中放置任何一个测试,它都会显示它。当我把两个都放进去时,它没有。相反,它显示 3andrew 和 andrew2 作为记录结果,这对我来说是出乎意料的,因为这个例子让我相信它像 AND 一样工作。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

所以你的模式 pattern (test test2) 按照我的理解是说找到一行 test 通过和后一行 test2 通过。

MATCH_RECOGNIZE 表示两个规则之间的运算符 (空格):

<块引用>

串联。指定一个符号或操作应该跟随另一个符号或操作。例如,S1 S2 表示为 S2 定义的条件应该出现在为 S1 定义的条件之后。

但我怀疑您的问题是为什么第 1 行在 test 上不匹配,然后第 3 行在 test2 上匹配......我相信这是 AFTER MATCH SKIP 的默认值 { {1}} 查找第 1 行和第 2 行匹配测试,因此它在最后一个之后开始,因此您只能获得一个匹配项。并不是说我可以使用该部分来关闭此行为。

如果我稍微改变输入数据:

PAST LAST ROW

这给出:

WITH names(id, name, groupid) as (
    SELECT * FROM VALUES
        (10, 'andrew', 1),
        (20, '2andrew', 1),
        (30, 'andrew3', 1),
        (40, 'simeon', 1),
        (50, '4andrew', 1)
) 

所以第 10 行可以工作,但似乎在您的数据中 2 绑定更接近 3,但在我的数据中 30 与 50 不匹配。另外值得注意的是,您的匹配中没有 order by 子句,这意味着您可能会得到不确定的结果。除非你在别处对你的数据重新排序..

因此更改添加 ID NAME GROUPID classifier 10 andrew 1 TEST 20 2andrew 1 TEST2 partition 子句意味着两个安德鲁斯现在都触发:

order

答案 1 :(得分:1)

模式是(test test2),这意味着找到恰好一行And开头的行紧跟着一行,后缀为rew . 图案窗口的大小为 2。

行处理如下:

1 andrew
2 andrew2
3 3andrew

第 1 关:

1 andrew
2 andrew2  -- fails it is not test2

第 2 步(此时跳过第 1 行):

2 andrew2   -- test  pass
3 3andrew   -- test2 pass

返回第 2 行和第 3 行并再次开始搜索过程(如果它们仍然是要处理的行)。

如果你想要任意数量的测试,那么模式应该是 (test+ test2) -(窗口大小至少为 2)。

如果您希望元素成为两者之一,则模式应为 (test|test2) -(窗口大小为 1)。


推荐阅读:match_recognize — Regular Expressions Over Rows