本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
聚合函数
聚合函数不是返回从单行计算得出的结果,而是返回根据有限行集合中包含的聚合数据或有关有限行集的信息计算得出的结果。聚合函数可能出现在以下任何内容中:
-
SELECT 子句的 <selection list> 部分
聚合函数不同于分析函数,它们总是相对于必须指定的窗口进行求值,因此它们不能出现在 HAVING 子句中。本主题后面的表格中描述了其他差异。
聚合函数在表聚合查询中的操作方式与在流的聚合查询中使用聚合函数时的操作方式略有不同,如下所示。如果对表的聚合查询包含 GROUP BY 子句,则聚合函数在输入行集合中为每组返回一个结果。缺少显式 GROUP BY 子句等同于 GROUP BY (),并且只为整组输入行返回一个结果。
在流上,聚合查询必须包含基于行时间的单调表达式上的显式 GROUP BY 子句。如果没有一个,唯一的组就是整个直播,它永远不会结束,无法报告任何结果。添加基于单调表达式的 GROUP BY 子句将流分解为时间连续的有限行集,然后可以聚合和报告每个这样的集合。
每当到达的行改变了单调分组表达式的值时,就会启动一个新组并认为前一组已完成。然后,Amazon Kinesis Data Analytics 应用程序输出聚合函数的值。请注意,GROUP BY 子句还可能包括其他非单调表达式,在这种情况下,每组行可能会产生多个结果。
对流执行聚合查询通常被称为流式聚合,这与中讨论的窗口化聚合不同分析函数和直播窗口聚合. 有关更多信息 stream-to-stream 联接,请参阅加入子句.
如果输入行包含null在用作数据分析函数输入的列中,数据分析函数忽略该行(COUNT 除外)。
流式聚合和行时界限
通常,当一行到达时,聚合查询会生成一个结果,该结果会改变 GROUP BY 中单调表达式的值。例如,如果查询按 FLOOR(行时间到分钟)分组,而当前行的行时间为 9:59 .30,则行时间为 10:00 .00 的新行将触发结果。
或者,可以使用行时界限来推进单调表达式并使查询返回结果。例如,如果查询按 FLOOR(行时间到分钟)分组,而当前行的行时间为 9:59 .30,则传入的行时间界限为 10:00 .00,则查询将返回结果。
聚合函数列表
Amazon Kinesis Data Analytics 支持以下聚合函数:
以下 SQL 使用 AVG 聚合函数作为查询的一部分来查找所有员工的平均年龄:
SELECT AVG(AGE) AS AVERAGE_AGE FROM SALES.EMPS;
结果:
| AVERAGE_AGE |
|---|
|
38 |
要计算每个部门员工的平均年龄,我们可以在查询中添加明确的 GROUP BY 子句:
SELECT DEPTNO, AVG(AGE) AS AVERAGE_AGE FROM SALES.EMPS GROUP BY DEPTNO;
返回值:
| DEPTNO | AVERAGE_AGE |
|---|---|
|
10 |
30 |
|
20 |
25 |
|
30 |
40 |
|
40 |
57 |
流上聚合查询(流式聚合)的示例
在此示例中,假设下表中的数据正在流经名为 WEATHERSTREAM 的流。
| ROWTIME | CITY | TEMP |
|---|---|---|
|
2018-11-00 |
丹佛 |
29 |
|
2018-11-00 |
安克雷奇 |
2 |
|
2018-11-00 |
迈阿密 |
65 |
|
2018-11-00 |
丹佛 |
32 |
|
2018-11-0 |
安克雷奇 |
9 |
|
2018-11-0 |
丹佛 |
50 |
|
2018-11-00 |
安克雷奇 |
10 |
|
2018-11-0 |
迈阿密 |
71 |
|
2018-11-0 |
丹佛 |
43 |
|
2018-11-00 |
安克雷奇 |
4 |
|
2018-11-00 |
丹佛 |
39 |
|
2018-11-00 |
丹佛 |
46 |
|
2018-11-00 |
安克雷奇 |
3 |
|
2018-11-00 |
丹佛 |
56 |
|
2018-11-00 |
安克雷奇 |
2 |
|
2018-11-00 |
丹佛 |
50 |
|
2018-11-00 |
丹佛 |
36 |
|
2018-11-00 |
安克雷奇 |
1 |
如果要查找每天任何地方(无论城市如何,全球)记录的最低和最高温度,可以分别使用聚合函数 MIN 和 MAX 来计算最低和最高温度。要表示我们每天需要此类信息(以及要提供单调表达式作为 GROUP BY 子句的参数),我们使用 FLOOR 函数将每个行的行时间向下取整为最近一天:
SELECT STREAM FLOOR(WEATHERSTREAM.ROWTIME to DAY) AS FLOOR_DAY, MIN(TEMP) AS MIN_TEMP, MAX(TEMP) AS MAX_TEMP FROM WEATHERSTREAM GROUP BY FLOOR(WEATHERSTREAM.ROWTIME TO DAY);
聚合查询的结果见下表。
| FLOOR_DAY | MIN_TEMP | MAX_TEMP |
|---|---|---|
|
2018-11-01 00:00:00 .0 |
2 |
71 |
|
2018-11-00 |
2 |
56 |
尽管示例数据确实包含当天的温度测量值,但2018-11-03没有行。这是因为在已知当天的所有行都已到达之前,无法对2018-11-03的行进行聚合,并且只有当行时间为2018-11-04 00:00:00 .0(或更晚)的行到达时,才会发生这种情况。如果两者何时到达,下一个结果将如下表所示。
| FLOOR_DAY | MIN_TEMP | MAX_TEMP |
|---|---|---|
|
2018-11-03 00:00:00 .0 |
1 |
36 |
假设我们想要找到每个城市每天的最低、最高和平均温度,而不是寻找全球每天的最低和最高气温。为此,我们使用 SUM 和 COUNT 聚合函数来计算平均值,并将 CITY 添加到 GROUP BY 子句中,如下所示:
SELECT STREAM FLOOR(WEATHERSTREAM.ROWTIME TO DAY) AS FLOOR_DAY, CITY, MIN(TEMP) AS MIN_TEMP, MAX(TEMP) AS MAX_TEMP, SUM(TEMP)/COUNT(TEMP) AS AVG_TEMP FROM WEATHERSTREAM GROUP BY FLOOR(WEATHERSTREAM.ROWTIME TO DAY), CITY;
聚合查询的结果见下表。
| FLOOR_DAY | CITY | MIN_TEMP | MAX_TEMP | AVG_TEMP |
|---|---|---|---|---|
|
2018-11-01 00:00:00 .0 |
安克雷奇 |
2 |
10 |
7 |
|
2018-11-01 00:00:00 .0 |
丹佛 |
29 |
50 |
38 |
|
2018-11-01 00:00:00 .0 |
迈阿密 |
65 |
71 |
68 |
|
2018-11-00 |
安克雷奇 |
2 |
4 |
3 |
|
2018-11-00 |
丹佛 |
39 |
56 |
47 |
在这种情况下,新一天温度测量值的行的到来会触发前一天数据的聚合,按城市分组,然后生成当天测量中包含的每个城市一行。
同样,在下表显示了2018-11-04的任何实际测量结果之前,可以使用2018-11-04 00:00:00 .0 来提示2018-11-03的结果。
| FLOOR_DAY | CITY | MIN_TEMP | MAX_TEMP | AVG_TEMP |
|---|---|---|---|---|
|
2018-11-03 00:00:00 .0 |
安克雷奇 |
1 |
1 |
1 |
|
2018-11-03 00:00:00 .0 |
丹佛 |
36 |
36 |
36 |