Flink SQL Over 聚合详解

Over 聚合定义(⽀持 Batch\Streaming):**特殊的滑动窗⼝聚合函数,拿 Over 聚合 与 窗⼝聚合 做对⽐。

窗⼝聚合:不在 group by 中的字段,不能直接在 select 中拿到

Over 聚合:能够保留原始字段

注意: ⽣产环境中,Over 聚合的使⽤场景较少。

**应⽤场景:**计算最近⼀段滑动窗⼝的聚合结果数据。

**实际案例:**查询每个产品最近⼀⼩时订单的⾦额总和:

复制代码
SELECT order_id,
	order_time,
  amount,
 	SUM(amount) OVER (
 		PARTITION BY product
 		ORDER BY order_time
 		RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW
 ) AS one_hour_prod_amount_sum
FROM Orders

Over 聚合语法如下:

复制代码
SELECT
 agg_func(agg_col) OVER (
 [PARTITION BY col1[, col2, ...]]
 ORDER BY time_col
 range_definition),
 ...
FROM ...

ORDER BY:必须是时间戳列(事件时间、处理时间);

PARTITION BY:标识了聚合窗⼝的聚合粒度,如上述案例是按照 product 进⾏聚合;

range_definition:标识聚合窗⼝的聚合数据范围,在 Flink 中有两种指定数据范围的⽅式。第⼀种为 按照⾏数聚合 ,第⼆种为 按照时间区间聚合 。

1.时间区间聚合

**案例:**输出一个产品最近⼀⼩时数据的 amount 之和。

结果就是最近⼀⼩时数据的 amount 之和。

复制代码
CREATE TABLE source_table (
 order_id BIGINT,
 product BIGINT,
 amount BIGINT,
 order_time as cast(CURRENT_TIMESTAMP as TIMESTAMP(3)),
 WATERMARK FOR order_time AS order_time - INTERVAL '0.001' SECOND
) WITH (
 'connector' = 'datagen',
 'rows-per-second' = '1',
 'fields.order_id.min' = '1',
 'fields.order_id.max' = '2',
 'fields.amount.min' = '1',
 'fields.amount.max' = '10',
 'fields.product.min' = '1',
 'fields.product.max' = '2'
);

CREATE TABLE sink_table (
 product BIGINT,
 order_time TIMESTAMP(3),
 amount BIGINT,
 one_hour_prod_amount_sum BIGINT
) WITH (
 'connector' = 'print'
);

INSERT INTO sink_table
SELECT product,
	order_time,
  amount,
 SUM(amount) OVER (
 	PARTITION BY product
 	ORDER BY order_time
 	-- 标识统计范围是⼀个 product 的最近 1 ⼩时的数据
 	RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW
 ) AS one_hour_prod_amount_sum
FROM source_table

结果如下:

复制代码
+I[2, 2021-12-24T22:08:26.583, 7, 73]
+I[2, 2021-12-24T22:08:27.583, 7, 80]
+I[2, 2021-12-24T22:08:28.583, 4, 84]
+I[2, 2021-12-24T22:08:29.584, 7, 91]
+I[2, 2021-12-24T22:08:30.583, 8, 99]
+I[1, 2021-12-24T22:08:31.583, 9, 138]
+I[2, 2021-12-24T22:08:32.584, 6, 105]
+I[1, 2021-12-24T22:08:33.584, 7, 145]
2.⾏数聚合

**案例:**输出一个产品最近 5 ⾏数据的 amount 之和。

复制代码
CREATE TABLE source_table (
 order_id BIGINT,
 product BIGINT,
 amount BIGINT,
 order_time as cast(CURRENT_TIMESTAMP as TIMESTAMP(3)),
 WATERMARK FOR order_time AS order_time - INTERVAL '0.001' SECOND
) WITH (
 'connector' = 'datagen',
 'rows-per-second' = '1',
 'fields.order_id.min' = '1',
 'fields.order_id.max' = '2',
 'fields.amount.min' = '1',
 'fields.amount.max' = '2',
 'fields.product.min' = '1',
 'fields.product.max' = '2'
);

CREATE TABLE sink_table (
 product BIGINT,
 order_time TIMESTAMP(3),
 amount BIGINT,
 one_hour_prod_amount_sum BIGINT
) WITH (
 'connector' = 'print'
);

INSERT INTO sink_table
SELECT product,
	order_time,
  amount,
 SUM(amount) OVER (
 PARTITION BY product
 ORDER BY order_time
 -- 标识统计范围是⼀个 product 的最近 5 ⾏数据
 ROWS BETWEEN 5 PRECEDING AND CURRENT ROW
 ) AS one_hour_prod_amount_sum
FROM source_table

结果如下:

复制代码
+I[2, 2021-12-24T22:18:19.147, 1, 9]
+I[1, 2021-12-24T22:18:20.147, 2, 11]
+I[1, 2021-12-24T22:18:21.147, 2, 12]
+I[1, 2021-12-24T22:18:22.147, 2, 12]
+I[1, 2021-12-24T22:18:23.148, 2, 12]
+I[1, 2021-12-24T22:18:24.147, 1, 11]
+I[1, 2021-12-24T22:18:25.146, 1, 10]
+I[1, 2021-12-24T22:18:26.147, 1, 9]
+I[2, 2021-12-24T22:18:27.145, 2, 11]
+I[2, 2021-12-24T22:18:28.148, 1, 10]
+I[2, 2021-12-24T22:18:29.145, 2, 10]

在⼀个 SELECT 中有多个聚合窗⼝,简化写法如下:

复制代码
SELECT order_id,
	order_time,
  amount,
 SUM(amount) OVER w AS sum_amount,
 AVG(amount) OVER w AS avg_amount
FROM Orders
-- 使⽤下⾯⼦句,定义 Over Window
WINDOW w AS (
 PARTITION BY product
 ORDER BY order_time
 RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW)
相关推荐
熊文豪14 小时前
KingbaseES电科金仓数据库SQL调优
数据库·sql·kingbasees·电科金仓·kes·sql调优
TaoSense14 小时前
Milvus向量数据库介绍
大数据·人工智能
智海观潮14 小时前
聊聊Spark的分区
java·大数据·spark
洛克大航海14 小时前
集群环境安装与部署 Hadoop
大数据·hadoop·ubuntu·集群部署 hadoop
EasyCVR15 小时前
赋能智慧水利:视频汇聚平台EasyCVR智慧水利工程视频管理系统解决方案
大数据
程序员洲洲16 小时前
使用亮数据爬虫API一键式爬取Facebook数据
大数据·数据·亮数据·bright data·爬虫api
2301_8002561117 小时前
地理空间数据库作业笔记——酒驾交通事故分析
sql·postgresql·1024程序员节
汽车仪器仪表相关领域17 小时前
工业商业安全 “哨兵”:GT-NHVR-20-A1 点型可燃气体探测器实操解析与场景适配
大数据·人工智能·功能测试·安全·安全性测试
ctrigger17 小时前
电子信息三胞胎:电子信息工程、电子科学技术、电子信息科学技术
大数据·注册电气工程师
得物技术18 小时前
告别数据无序:得物数据研发与管理平台的破局之路
大数据·数据库·数据分析