1

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

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 一样工作。任何帮助表示赞赏。

4

2 回答 2

2

该模式(test test2)意味着找到恰好一行以And 开头的行,然后是具有rew后缀的行。图案窗口的大小为 2。

行处理如下:

1 andrew
2 andrew2
3 3andrew

通过1:

1 andrew
2 andrew2  -- fails it is not test2

Pass 2(此时跳过了第 1 行):

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

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

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

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


推荐阅读:match_recognize — 行上的正则表达式

于 2021-04-26T09:02:15.463 回答
0

因此,据我所知,您的模式pattern (test test2)是说找到通过的行testtest2通过的后行。

MATCH_RECOGNIZE表示 您在两条规则之间拥有的运算符(空格):

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

但我怀疑你的问题是为什么第 1 行不匹配test然后第 3 行匹配test2.. 我相信这是查找第 1 行和第 2 行匹配测试AFTER MATCH SKIP的默认值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)
) 

这给出了:

ID  NAME    GROUPID classifier
10  andrew  1   TEST
20  2andrew 1   TEST2

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

因此更改添加partitionandorder子句意味着两个安德鲁斯现在都触发:

WITH names(id, name, groupid) as (
    SELECT * FROM VALUES
        (10, 'andrew', 1),
        (11, 'simeon', 2),
        (20, '2andrew', 1),
        (30, 'andrew3', 1),
        (60, 'simeon', 1),
        (50, '4andrew', 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
;   
于 2021-04-26T04:05:55.620 回答