FlinkSql系列8之TopN&去重

FlinkSql系列8之TopN&去重


前言

本次主要记录FLinkSql中的TopN以及去重。

一、TopN

建立数据源表

CREATE TABLE source_table5(
--姓名
`name` STRING,
--班级
`class_id` BIGINT,
--分数
`score` BIGINT,
--事件时间
`row_time` TIMESTAMP(3),
--watermark设置
WATERMARK for row_time AS row_time
) WITH (
 'connector' = 'kafka',
 'topic' = 'flinksql002',
 'properties.bootstrap.servers' = 'xxxx:9092',
 'properties.group.id' = 'testGroup',
 'scan.startup.mode' = 'latest-offset',
 'format' = 'csv'
)

场景:统计每个班级的前三名

SELECT
name,
class_id,
score,
row_time
FROM (
SELECT 
name,
class_id,
score,
row_time,
ROW_NUMBER() OVER(
PARTITION BY class_id
ORDER BY score DESC) as rownum
FROM source_table5
) WHERE rownum<=3;

测试截图展示:
在这里插入图片描述

在这里插入图片描述
可以看到随着时间的推移,数据到来,已经输出三条了
在这里插入图片描述
紧接着这里我们又来一条比之前分数高的,可以看下输出结果,之前的一条被撤回了
在这里插入图片描述

注意:
这里为什么数据会有撤回流,是因为在整个流式计算中,数据源源不断的到来,而我们并没有划定窗口的界限,因此相当于flink缓存了中间所有数据的状态,然后每次都要筛选一遍,得出结果,这对于大状态很容易有问题!

二、WindowTopN

源表依然是上面建的表
下面我们的场景是统计每个班级在一分钟内的时间窗口内的前三名的情况。

SELECT 
name,
class_id,
score,
window_start,
window_end
FROM (
SELECT 
name,
class_id,
score,..
window_start,
window_end,
ROW_NUMBER() OVER(
PARTITION BY window_start,window_end,class_id
ORDER BY score DESC) as rownum
FROM (
SELECT 
name,
class_id,
max(score) as score,
window_start,
window_end
FROM
TABLE(
TUMBLE(
TABLE source_table5,
DESCRIPTOR(row_time),
INTERVAL '1' MINUTE))
GROUP BY window_start,window_end,class_id,name)) WHERE rownum<=3

这里当我们最后输入这个数据的时候就会触发整个计算
在这里插入图片描述
计算的结果
在这里插入图片描述
这里有个注意点就是这里的模式是固定的:直接写子查询那一段是报错的,会报错
在这里插入图片描述
因此这里是有模板的:

SELECT [column_list]
FROM (
 SELECT [column_list],
 ROW_NUMBER() OVER (PARTITION BY window_start, window_end [, col_key1...]
 ORDER BY col1 [asc|desc][, col2 [asc|desc]...]) AS rownum
 FROM table_name) -- windowing TVF
WHERE rownum <= N [AND conditions]

需要严格遵守整个模板才可以。

三、Deduplication

本次场景来实现对以一个指标下的数据的去重:

创建数据源表:

CREATE TABLE source_table8(
--用户id
`user_id` BIGINT,
--用户等级
`user_level` STRING,
--访问时间
`row_time` TIMESTAMP(3),
--watermark设置
WATERMARK FOR row_time AS row_time
) WITH (
 'connector' = 'kafka',
 'topic' = 'flinksql002',
 'properties.bootstrap.servers' = 'xxxx:9092',
 'properties.group.id' = 'testGroup',
 'scan.startup.mode' = 'latest-offset',
 'format' = 'csv'
)

执行sql:

SELECT
user_level,
count(1) as uv
FROM(
SELECT
user_id,
user_level,
ROW_NUMBER() OVER(
PARTITION BY user_id
ORDER BY row_time) as rownum
FROM
source_table8
)
WHERE rownum = 1
GROUP BY
user_level

在这里插入图片描述
在这里插入图片描述

总结

本次主要记录TopN以及Winodow的TopN,需要注意的是这还是有模板可参考的,最后还用ROW_NUMBER() 进行去重的操作。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值