Calcite中的流式SQL总体设计思路
  总体语法应该兼容SQL,这个是和目前流处理SQL的发展趋势是一致的。
  如果部分功能标准SQL中没有包含,则尽量采用 业界标杆(Oracle) 。比如模式匹配的功能,目前流处理中还没有针对语法达成共识,那么在设计上,采用Oracle data warehouse的Match Recognize的方式。还有滑窗功能。
  如果还有功能目前业界标杆都没有,那么通过函数的方式拓展,翻滚窗口和跳动窗口,这两个窗口在标准SQL中都是不包含的,所以采用了Ceil,Tumble,Hop等函数的方式来实现功能。
  总体思路是 在兼容标准SQL的基础上做尽可能少的拓展,保证语义和标准SQL一致,尽大可能减少私有化的语法 。
  Calcite StreamSQL说明
  1、在DDL中明确定义schema是流Or表,TODO:官网没有示例,待补充
  比如有三张schema:
  Orders (rowtime, productId, orderId, units) - 既是表,又是流
  Products (rowtime, productId, name) - 表
  Shipments (rowtime, orderId) - 流
  2、查询中如果包含Stream关键字,是流式查询,如果不包含,是表查询。表查询可以马上返回结果并结束,流式查询只会输出结果但并不结束。
  比如下面一个流查询示例:
  SELECT STREAM *
  FROM Orders;
  rowtime | productId | orderId | units
  ----------+-----------+---------+-------
  10:17:00 |        30 |       5 |     4
  10:17:05 |        10 |       6 |     1
  10:18:05 |        20 |       7 |     2
  10:18:07 |        30 |       8 |    20
  11:02:00 |        10 |       9 |     6
  11:04:00 |        10 |      10 |     1
  11:09:30 |        40 |      11 |    12
  11:24:11 |        10 |      12 |     4
  表查询示例:
  SELECT *
  FROM Orders;
  rowtime | productId | orderId | units
  ----------+-----------+---------+-------
  08:30:00 |        10 |       1 |     3
  08:45:10 |        20 |       2 |     1
  09:12:21 |        10 |       3 |    10
  09:27:44 |        30 |       4 |     2
  4 records returned.
  流和表的查询不能混用,否则会报错
  SELECT * FROM Shipments;
  ERROR: Cannot convert stream 'SHIPMENTS' to a table
  SELECT STREAM * FROM Products;
  ERROR: Cannot convert table 'PRODUCTS' to a stream
  1、其他过滤,排序,having等操作和标准sql一致,不再举例。
  2、子查询只需要在外层语句写Stream关键字即可,内层写了无效。
  如:
  SELECT STREAM rowtime, productId
  FROM (
  SELECT TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
  productId,
  COUNT(*) AS c,
  SUM(units) AS su
  FROM Orders
  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId)
  WHERE c > 2 OR su > 10;
  rowtime | productId
  ----------+-----------
  10:00:00 |        30
  11:00:00 |        10
  11:00:00 |        40
  窗口功能说明
  翻滚窗(Tumbling window)
  两个窗口之间数据没有重叠。
  SELECT STREAM CEIL(rowtime TO HOUR) AS rowtime,
  productId,
  COUNT(*) AS c,
  SUM(units) AS units
  FROM Orders
  GROUP BY CEIL(rowtime TO HOUR), productId;
  rowtime | productId |       c | units
  ----------+-----------+---------+-------
  11:00:00 |        30 |       2 |    24
  11:00:00 |        10 |       1 |     1
  11:00:00 |        20 |       1 |     7
  12:00:00 |        10 |       3 |    11
  12:00:00 |        40 |       1 |    12
  该示例每个小时结束的时候,输出这个小时的统计结果,11点整,输出1点的统计结果。以事件为驱动,内部不包含定时器。
  下面的例子和上面的例子等价
  SELECT STREAM TUMBLE_END(rowtime, INTERVAL '1' HOUR) AS rowtime,
  productId,
  COUNT(*) AS c,
  SUM(units) AS units
  FROM Orders
  GROUP BY TUMBLE(rowtime, INTERVAL '1' HOUR), productId;
  rowtime | productId |       c | units
  ----------+-----------+---------+-------
  11:00:00 |        30 |       2 |    24
  11:00:00 |        10 |       1 |     1
  11:00:00 |        20 |       1 |     7
  12:00:00 |        10 |       3 |    11
  12:00:00 |        40 |       1 |    12
  又比如,需要没半个小时输出一次结果,以12分钟为对齐时间,
  SELECT STREAM
  TUMBLE_END(rowtime, INTERVAL '30' MINUTE, TIME '0:12') AS rowtime,
  productId,
  COUNT(*) AS c,
  SUM(units) AS units
  FROM Orders
  GROUP BY TUMBLE(rowtime, INTERVAL '30' MINUTE, TIME '0:12'),
  productId;
  rowtime | productId |       c | units
  ----------+-----------+---------+-------
  10:42:00 |        30 |       2 |    24
  10:42:00 |        10 |       1 |     1
  10:42:00 |        20 |       1 |     7
  11:12:00 |        10 |       2 |     7
  11:12:00 |        40 |       1 |    12
  11:42:00 |        10 |       1 |     4
  跳动窗(HOP window)
  两个窗口之间的数据有一定重叠。
  跳动窗口是广义化的翻滚窗,允许数据在窗口中保存更长时间。
  比如下面的例子,数据输出时间为11:00,但是其中还包含08:00到11:00的数据,以及09:00到12:00的数据,一个输入行对应三个输出行。
  SELECT STREAM
  HOP_END(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR) AS rowtime,
  COUNT(*) AS c,
  SUM(units) AS units
  FROM Orders
  GROUP BY HOP(rowtime, INTERVAL '1' HOUR, INTERVAL '3' HOUR);
  rowtime |        c | units
  ----------+----------+-------
  11:00:00 |        4 |    27
  12:00:00 |        8 |    50
  滑动窗(sliding window)
  Calcite中的滑动窗采用标准的Over方式,直接套用了标准SQL中的分析函数。
  SELECT STREAM rowtime,
  productId,
  units,
  SUM(units) OVER (ORDER BY rowtime RANGE INTERVAL '1' HOUR PRECEDING) unitsLastHour
  FROM Orders;
  下面的一个例子展示了过去10分钟的平均订单大小和上周平均订单的比较数据
  SELECT STREAM *
  FROM (
  SELECT STREAM rowtime,
  productId,
  units,
  AVG(units) OVER product (RANGE INTERVAL '10' MINUTE PRECEDING) AS m10,
  AVG(units) OVER product (RANGE INTERVAL '7' DAY PRECEDING) AS d7
  FROM Orders
  WINDOW product AS (
  ORDER BY rowtime
  PARTITION BY productId))
  WHERE m10 > d7;
  在这个例子中,使用Window子句来定义部分窗口,然后在每个OVER子句中在进行细化。初次之外,还可以在window子句中定义所有的窗口。
  这种实现方式中,在后台同时维护了两张表,10分钟和7天的窗口数据。你可以直接访问到这些表,不需要做显示的查询。
  这种语法还可以实现其他一些功能:
  * 行组窗口
  * 引用尚未到达的行,流将等待,直到它们到达。
  * 可以支持其他RANK等统计分析函数