Apache Calcite官方文档中文版- 进阶-3( 二 )


是如何知道10:00:00的小计在11:00:00完成的,这样就可以发出它们了?它知道是在增加,而且它也知道CEIL( TO HOUR)在增加 。所以,一旦在11:00:00时间点或之后看到一行,它将永远不会看到贡献到上午10:00:00的一行 。
增加或减少的列以及表达式是单调的 。(单调递增或单调递减)
如果列或表达式的值具有轻微的失序,并且流具有用于声明特定值将不会再被看到的机制(例如标点符号或水印),则该列或表达式被称为准单调 。
在GROUP BY子句中没有单调或准单调表达式的情况下,无法取得进展,并且不允许查询:
SELECT STREAM productId,COUNT(*) AS c,SUM(units) AS unitsFROM OrdersGROUP BY productId;ERROR: Streaming aggregation requires at least one monotonic expression
单调和准单调的列需要在模式中声明 。当记录输入流并且由从该流中读取数据的假定查询时,单调性被强制执行 。我们建议为每个流指定一个时间戳列,但也可以声明其他列是单调的,例如 。
我们将在下面的内容讨论标点符号,水印,并取得进展的其他方法 。
3.7 滚动窗口,改进
前面的滚动窗口的例子很容易写,因为窗口是一个小时 。对于不是整个时间单位的时间间隔,例如2小时或2小时17分钟,则不能使用CEIL,表达式将变得更复杂 。
支持滚动窗口的替代语法:
SELECT STREAM TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,productId,COUNT(*) AS c,SUM(units) AS unitsFROM OrdersGROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId;rowtime | productId |c | units----------+-----------+---------+-------11:00:00 |30 |2 |2411:00:00 |10 |1 |111:00:00 |20 |1 |712:00:00 |10 |3 |1112:00:00 |40 |1 |12
正如你所看到的,它返回与前一个查询相同的结果 。函数返回一个分组键,这个分组键在给定的汇总行中将会以相同的方式结束;函数采用相同的参数并返回该窗口的结束时间; 当然还有一个函数 。
有一个可选参数来对齐窗口 。在以下示例中,我们使用30分钟间隔和0:12作为对齐时间,因此查询在每小时过去12分钟和42分钟时发出汇总:
SELECT STREAMTUMBLE_END(rowtime, INTERVAL '30' MINUTE, TIME '0:12') AS rowtime,productId,COUNT(*) AS c,SUM(units) AS unitsFROM OrdersGROUP BY TUMBLE(rowtime, INTERVAL '30' MINUTE, TIME '0:12'),productId;rowtime | productId |c | units----------+-----------+---------+-------10:42:00 |30 |2 |2410:42:00 |10 |1 |110:42:00 |20 |1 |711:12:00 |10 |2 |711:12:00 |40 |1 |1211:42:00 |10 |1 |4
3.8 跳转窗口
跳转窗口是滚动窗口的泛化(概括),它允许数据在窗口中保持比发出间隔更长的时间 。
查询发出的行的时间戳11:00,包含数据从08:00至11:00(或10:59.9);以及行的时间戳12:00,包含数据从09:00至12:00 。
SELECT STREAMHOP_END(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR) AS rowtime,COUNT(*) AS c,SUM(units) AS unitsFROM OrdersGROUP BY HOP(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR);rowtime |c | units----------+----------+-------11:00:00 |4 |2712:00:00 |8 |50
在这个查询中,因为保留期是发出期的3倍,所以每个输入行都贡献到3个输出行 。想象一下,HOP函数为传入行生成一组Group Keys,并将其值存储在每个Group Key的累加器中 。例如,HOP(10:18:00,'1' HOUR,'3')产生3个时间间隔周期:
[08:00, 09:00)
[09:00, 10:00)
[10:00, 11:00)
这就提出了允许不满意内置函数HOP和的用户来自定义的分区函数的可能性 。
我们可以建立复杂的复杂表达式,如指数衰减的移动平均线:
SELECT STREAM HOP_END(rowtime),productId,SUM(unitPrice * EXP((rowtime - HOP_START(rowtime)) SECOND / INTERVAL '1' HOUR))/ SUM(EXP((rowtime - HOP_START(rowtime)) SECOND / INTERVAL '1' HOUR))