聚合函数 - Amazon Kinesis Data Analytics
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

聚合函数

聚合函数返回通过包含在一组有限数量的行中的聚合数据或通过有关一组有限数量的行的信息计算出的结果,而不是返回通过一个行计算出的结果。聚合函数可能在以下任一条件下出现:

聚合函数不同于分析函数,该函数始终相对于必须指定的窗口进行计算,因此它们无法出现在 HAVING 子句中。其他区别将在本主题后面的表中说明。

聚合函数在对表进行的聚合查询中的运行方式与在对流的聚合查询中的运行方式略为不同,如下所示。如果对表的聚合查询包含 GROUP BY 子句,则聚合函数将在此组输入行中对每个组返回一个结果。缺少显式 GROUP BY 子句的情况等效于 GROUP BY (),而且仅为整组输入行返回一个结果。

在流上,聚合查询必须包含针对基于行时间的单调表达式的显式 GROUP BY 子句。如果没有此子句,唯一的组将是整个流,这将永不结束,从而会阻止报告任何结果。基于单调表达式添加 GROUP BY 子句可将流分成有限数量的行集,在时间上连续,然后可聚合和报告每个此类集合。

每当一个行到达单调分组表达式的值的更改时,将启动一个新组,并且上一组将被视为完成。然后,Amazon Kinesis Data Analytics 应用程序会输出聚合函数的值。请注意,GROUP BY 子句还可能包含其他非单调表达式,在这种情况下,每组行可能会生成多个结果。

对流执行聚合查询通常称作“流式处理聚合”,这与在分析函数流的窗口化聚合中讨论的窗口化聚合不同。有关流到流联接的更多信息,请参阅 JOIN 子句

如果输入行在列中包含用作数据分析函数输入的 null,则数据分析函数将忽略此行 (COUNT 除外)。

聚合函数和分析函数之间的区别
函数类型 输出 使用的行数或窗口数 备注

聚合函数

每组输入行有一个输出行。

所有输出列通过同一窗口或同一组行进行计算。

流式处理聚合中不允许使用 COUNT DISTINCT。不允许以下类型的语句:

SELECT COUNT(DISTINCT x) ...FROM ...GROUP BY ...

分析函数

每个输入行有一个输出行。

每个输出列可使用不同的窗口或分区进行计算。

COUNT DISTINCT 不能用作分析函数或在窗口化聚合中使用。

流式处理聚合和行时间边界

通常,聚合查询在行到达 GROUP BY 中的单调表达式的值的更改后会生成一个结果。例如,如果此查询按 FLOOR(rowtime TO MINUTE) 进行分组,而且当前行的行时间为 9:59.30,则行时间为 10:00.00 的新行将触发此结果。

或者,行时间边界可用于提升单调表达式并启用查询以返回结果。例如,如果此查询按 FLOOR(rowtime TO MINUTE) 进行分组,而且当前行的行时间为 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-01 01:00:00.0

Denver

29

2018-11-01 01:00:00.0

Anchorage

2

2018-11-01 06:00:00.0

Miami

65

2018-11-01 07:00:00.0

Denver

32

2018-11-01 09:00:00.0

Anchorage

9

2018-11-01 13:00:00.0

Denver

50

2018-11-01 17:00:00.0

Anchorage

10

2018-11-01 18:00:00.0

Miami

71

2018-11-01 19:00:00.0

Denver

43

2018-11-02 01:00:00.0

Anchorage

4

2018-11-02 01:00:00.0

Denver

39

2018-11-02 07:00:00.0

Denver

46

2018-11-02 09:00:00.0

Anchorage

3

2018-11-02 13:00:00.0

Denver

56

2018-11-02 17:00:00.0

Anchorage

2

2018-11-02 19:00:00.0

Denver

50

2018-11-03 01:00:00.0

Denver

36

2018-11-03 01:00:00.0

Anchorage

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-02 00:00:00.0

2

56

没有针对 2018-11-03 的行,即使示例数据包含当天的温度测量值。这是因为无法聚合针对 2018-11-03 的行,直到获知当天的所有行到达,而且仅在具有 2018-11-04 00:00:00.0 (或更晚) 的行时间的行或 2018-11-04 00:00:00.0 (或更晚) 的行时间边界到达时发生。只有当其中一个到达时,下一个结果才能在下表中描述。

FLOOR_DAY MIN_TEMP MAX_TEMP

2018-11-03 00:00:00.0

1

36

假设我们想要查找每个城市每天的最低、最高和平均温度,而不是查找每天的全球最低和最高温度。为此,我们使用 SUM 和 COUNT 聚合函数计划此平均值,并向 GROUP BY 子句添加 CITY,如下所示:

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

Anchorage

2

10

7

2018-11-01 00:00:00.0

Denver

29

50

38

2018-11-01 00:00:00.0

Miami

65

71

68

2018-11-02 00:00:00.0

Anchorage

2

4

3

2018-11-02 00:00:00.0

Denver

39

56

47

在这种情况下,针对新一天的温度测量值的行的到达会触发前一天的数据的聚合 (按 CITY 分组),从而导致针对每个城市生成的一个行将包含在当天的测量值中。

同样,行时间边界 2018-11-04 00:00:00.0 可用于在进入 2018-11-04 后的任何实际测量值之前提示 2018-11-03 的结果,如下表所示。

FLOOR_DAY CITY MIN_TEMP MAX_TEMP AVG_TEMP

2018-11-03 00:00:00.0

Anchorage

1

1

1

2018-11-03 00:00:00.0

Denver

36

36

36