事件窗口

通过基于事件的窗口,可以将时序数据拆分为与数据中的重大事件相邻的窗口。这在财务数据中尤其重要,因为分析通常可以侧重于触发了其他活动的特定事件。

Vertica 提供了两个不属于 SQL-99 标准的基于事件的窗口函数:

  • CONDITIONAL_CHANGE_EVENT 从 0 开始向每个行分配一个事件窗口编号,并在当前行中评估实参表达式的结果与上一行不同时,以 1 为增量递增事件窗口编号。此函数与 ROW_NUMBER 分析函数类似,该分析函数从 1 开始按顺序向分区中每个行分配一个唯一编号。

  • CONDITIONAL_TRUE_EVENT 从 0 开始向每个行分配一个事件窗口编号,并在当 boolean 实参表达式的结果评估为 true 时,以 1 为增量递增事件窗口编号。

下文中更详细地介绍了这两种函数。

示例架构

此页面中的示例使用以下架构:

CREATE TABLE TickStore3 (ts TIMESTAMP, symbol VARCHAR(8), bid FLOAT);
CREATE PROJECTION TickStore3_p (ts, symbol, bid) AS SELECT * FROM TickStore3 ORDER BY ts, symbol, bid UNSEGMENTED ALL NODES;
INSERT INTO TickStore3 VALUES ('2009-01-01 03:00:00', 'XYZ', 10.0);
INSERT INTO TickStore3 VALUES ('2009-01-01 03:00:03', 'XYZ', 11.0);
INSERT INTO TickStore3 VALUES ('2009-01-01 03:00:06', 'XYZ', 10.5);
INSERT INTO TickStore3 VALUES ('2009-01-01 03:00:09', 'XYZ', 11.0);
COMMIT;

使用 CONDITIONAL_CHANGE_EVENT

CONDITIONAL_CHANGE_EVENT 分析函数会返回一系列表示从 0 开始的事件窗口编号的整数。当在当前行中评估函数表达式的结果与上一行不同时,函数会递增事件窗口编号。

在以下示例中,第一个查询会返回 TickStore3 表中的所有记录。第二个查询在出价列中使用 CONDITIONAL_CHANGE_EVENT 函数。由于每个出价行值与上一个值不同,函数会将窗口 ID 从 0 递增到 3。

下图以图表形式说明了出价的变化情况。每个值都不同于其前面的值,因此递增了每个时间片的窗口 ID:

条件更改事件

窗口 ID 从 0 开始,并在值每次与前一个值不同时递增。

在此示例中,出价在第二行中从 $10 变为 $11,然后保持不变。 CONDITIONAL_CHANGE_EVENT 递增了第 2 行的事件窗口 ID,但之后一直没有递增:

下图以图表形式说明了出价仅在 3:00:03 发生了变化。出价在 3:00:06 和 3:00:09 时没有变化,因此在上述变化之后,每个时间片的窗口 ID 仍为 1。

![CCE 2](/images/cce2.png)

使用 CONDITIONAL_TRUE_EVENT

CONDITIONAL_CHANGE_EVENT 一样,CONDITIONAL_TRUE_EVENT 分析函数也会返回一系列表示从 0 开始的事件窗口编号的整数。这两种函数的区别如下:

  • CONDITIONAL_TRUE_EVENT 每次窗口 ID 的表达式计算结果为 true 时,均会增加此 ID。

  • CONDITIONAL_CHANGE_EVENT 使用上一个值在比较表达式中递增。

在以下示例中,第一个查询会返回 TickStore3 表中的所有记录。第二个查询使用CONDITIONAL_TRUE_EVENT 测试当前出价是否大于给定值 (10.6)。每次表达式测试为 true 时,函数都会递增窗口 ID。函数第一次递增窗口 ID 是在第 2 行,这时的值为 11。如果在下一行中,表达式测试为 false(值不大于 10.6),函数不会递增事件窗口 ID。在最后一行中,对于给定的条件,表达式为 true,因此函数将递增窗口:

下图以图形方式显示了 bid 值和窗口 ID 的变化。因为出价值仅在第二个和第四个时间片(3:00:03 和 3:00:09)中大于 $10.6,窗口 ID 返回了 <0,1,1,2>:

CTE

在以下示例中,第一个查询返回了 TickStore3 表中所有的记录,且这些记录按 tickstore 值 (ts) 进行排序。每次出价值大于 10.6 时,第二个查询使用 CONDITIONAL_TRUE_EVENT 递增窗口 ID。函数第一次递增事件窗口 ID 是在第 2 行,这时的值为 11。此后,窗口 ID 每次都会递增,因为对于每个时间片,表达式 (bid > 10.6) 测试都为 true:

下图以图形方式显示了 bid 值和窗口 ID 的变化。出价值在第二个时间片 (3:00:03) 中大于 10.6,在后面两个时间片中也是如此。函数每次都会递增事件窗口 ID,因为表达式测试为 true:

cte2

基于事件的窗口的高级用法

在基于事件的窗口函数中,条件表达式只能访问当前行中的值。要访问前一个值,您可以使用更强大的基于事件的窗口,使窗口事件条件可以包含前一个数据点。例如,LAG(x, n) 分析函数会从上一个输入记录中检索列 x 中排在第 n 位的值。在这种情况下,LAG 共享 CONDITIONAL_CHANGE_EVENTCONDITIONAL_TRUE_EVENT 函数表达式的 OVER 规范。

在以下示例中,第一个查询会返回 TickStore3 表中的所有记录。第二个查询在其 boolean 表达式中结合 LAG 函数使用了 CONDITIONAL_TRUE_EVENT。在这种情况下,如果当前行的出价值小于前一个值,CONDITIONAL_TRUE_EVENT 每次会递增事件窗口 ID。CONDITIONAL_TRUE_EVENT 第一次递增窗口 ID 是在第三个时间片,这时的表达式测试为 ture。当前值 (10.5) 小于前一个值。由于最后一个值大于前一行,所以在最后一行中没有递增窗口 ID:

下图显示了上述第二个查询。当出价小于前一个值时,函数会递增窗口 ID,这仅会在第三个时间片 (3:00:06) 中发生:

cte3

另请参阅