SEQUENCE_MATCH
更新时间:2025-10-16
描述
检查序列是否包含与模式匹配的事件链。
警告!
在同一秒钟发生的事件可能以未定义的顺序排列在序列中,会影响最终结果。
语法
SQL
1SEQUENCE_MATCH(<pattern>, <timestamp>, <cond_1> [, <cond_2>, ..., <cond_n>])
参数
| 参数 | 说明 |
|---|---|
<pattern> |
模式字符串,可参考下面的模式语法 |
<timestamp> |
包含时间的列。典型的时间类型是: Date 和 DateTime。也可以使用任何支持的 UInt 数据类型。 |
<cond_n> |
事件链的约束条件。数据类型是: UInt8。最多可以传递 32 个条件参数。该函数只考虑这些条件中描述的事件。如果序列包含未在条件中描述的数据,则函数将跳过这些数据。 |
模式语法
(?N)— 在位置 N 匹配条件参数。条件在编号[1, 32]范围。例如,(?1)匹配传递给cond1参数。.*— 匹配任何事件的数字。不需要条件参数来匹配这个模式。(?t operator value)— 分开两个事件的时间。单位为秒。t表示为两个时间的差值,单位为秒。例如:(?1)(?t>1800)(?2)匹配彼此发生超过 1800 秒的事件,(?1)(?t>10000)(?2)匹配彼此发生超过 10000 秒的事件。这些事件之间可以存在任意数量的任何事件。您可以使用>=,>,<,<=,==运算符。
返回值
1:模式匹配。
0:模式不匹配。
举例
匹配例子
SQL
1CREATE TABLE sequence_match_test1(
2 `uid` int COMMENT 'user id',
3 `date` datetime COMMENT 'date time',
4 `number` int NULL COMMENT 'number'
5) DUPLICATE KEY(uid)
6DISTRIBUTED BY HASH(uid) BUCKETS AUTO
7PROPERTIES (
8 "replication_num" = "1"
9);
10
11INSERT INTO sequence_match_test1(uid, date, number) values
12(1, '2022-11-02 10:41:00', 1),
13(2, '2022-11-02 13:28:02', 2),
14(3, '2022-11-02 16:15:01', 1),
15(4, '2022-11-02 19:05:04', 2),
16(5, '2022-11-02 20:08:44', 3);
17
18
19SELECT
20sequence_match('(?1)(?2)', date, number = 1, number = 3) as c1,
21sequence_match('(?1)(?2)', date, number = 1, number = 2) as c2,
22sequence_match('(?1)(?t>=3600)(?2)', date, number = 1, number = 2) as c3
23FROM sequence_match_test1;
Text
1+------+------+------+
2| c1 | c2 | c3 |
3+------+------+------+
4| 1 | 1 | 1 |
5+------+------+------+
不匹配例子
SQL
1CREATE TABLE sequence_match_test2(
2 `uid` int COMMENT 'user id',
3 `date` datetime COMMENT 'date time',
4 `number` int NULL COMMENT 'number'
5) DUPLICATE KEY(uid)
6DISTRIBUTED BY HASH(uid) BUCKETS AUTO
7PROPERTIES (
8 "replication_num" = "1"
9);
10
11INSERT INTO sequence_match_test2(uid, date, number) values
12(1, '2022-11-02 10:41:00', 1),
13(2, '2022-11-02 11:41:00', 7),
14(3, '2022-11-02 16:15:01', 3),
15(4, '2022-11-02 19:05:04', 4),
16(5, '2022-11-02 21:24:12', 5);
17
18SELECT
19sequence_match('(?1)(?2)', date, number = 1, number = 2) as c1,
20sequence_match('(?1)(?2).*', date, number = 1, number = 2) as c2,
21sequence_match('(?1)(?t>3600)(?2)', date, number = 1, number = 7) as c3
22FROM sequence_match_test2;
Text
1+------+------+------+
2| c1 | c2 | c3 |
3+------+------+------+
4| 0 | 0 | 0 |
5+------+------+------+
特殊例子
SQL
1CREATE TABLE sequence_match_test3(
2 `uid` int COMMENT 'user id',
3 `date` datetime COMMENT 'date time',
4 `number` int NULL COMMENT 'number'
5) DUPLICATE KEY(uid)
6DISTRIBUTED BY HASH(uid) BUCKETS AUTO
7PROPERTIES (
8 "replication_num" = "1"
9);
10
11INSERT INTO sequence_match_test3(uid, date, number) values
12(1, '2022-11-02 10:41:00', 1),
13(2, '2022-11-02 11:41:00', 7),
14(3, '2022-11-02 16:15:01', 3),
15(4, '2022-11-02 19:05:04', 4),
16(5, '2022-11-02 21:24:12', 5);
17
18SELECT sequence_match('(?1)(?2)', date, number = 1, number = 5)
19FROM sequence_match_test3;
Text
1+----------------------------------------------------------------+
2| sequence_match('(?1)(?2)', `date`, `number` = 1, `number` = 5) |
3+----------------------------------------------------------------+
4| 1 |
5+----------------------------------------------------------------+
上面为一个非常简单的匹配例子,该函数找到了数字 5 跟随数字 1 的事件链。它跳过了它们之间的数字 7,3,4,因为该数字没有被描述为事件。如果我们想在搜索示例中给出的事件链时考虑这个数字,我们应该为它创建一个条件。
现在,考虑如下执行语句:
SQL
1SELECT sequence_match('(?1)(?2)', date, number = 1, number = 5, number = 4)
2FROM sequence_match_test3;
Text
1+------------------------------------------------------------------------------+
2| sequence_match('(?1)(?2)', `date`, `number` = 1, `number` = 5, `number` = 4) |
3+------------------------------------------------------------------------------+
4| 0 |
5+------------------------------------------------------------------------------+
您可能对这个结果有些许疑惑,在这种情况下,函数找不到与模式匹配的事件链,因为数字 4 的事件发生在 1 和 5 之间。如果在相同的情况下,我们检查了数字 6 的条件,则序列将与模式匹配。
SQL
1SELECT sequence_match('(?1)(?2)', date, number = 1, number = 5, number = 6)
2FROM sequence_match_test3;
Text
1+------------------------------------------------------------------------------+
2| sequence_match('(?1)(?2)', `date`, `number` = 1, `number` = 5, `number` = 6) |
3+------------------------------------------------------------------------------+
4| 1 |
5+------------------------------------------------------------------------------+
