00:00
接下来呢,我们再来介绍另外一类比较特殊的聚合方式啊,一般我们把它叫做开窗聚合,在标准CQ里边一般是使用S来进行定义的啊,所以它并不是flink CQ特有的聚合方式啊,这是通用的,那么它的主要特点就是它并不是针对当前我们一张数据表里边所有航数据去进行聚合。哎,我们知道在之前讲到的窗口聚合里边,不管是使用老版本的分组窗口聚合,还是新版本的窗口TF聚合,它的本质都是针对我们当前的某一列窗,当前表数据里边的某一列,然后开启一个窗口,那也就是要选选取很多行数据,然后得到一个唯一的聚合值进行统计计算啊,要用对应的那个聚合函数得到唯一的一个值,哎,所以相当于就是一个窗口。
01:05
一个值,一个窗口一个值。统计出来的结果是跟窗口的个数有关的,我们的结果表里面有多少个值,肯定是跟窗口有关,当然也跟我们划分那个group啊的那个key有关啊,那之前我们测试的结果都说明了这一点。而开窗聚合这个window它比较特殊,它是针对每一行都可以去计算一个聚合值。也就是说,我当年什么叫做开窗呢?就是针对当前表里面的某一行数据,我可以以它为基准,然后在它以上以下这个范围内。开这么一个窗口,然后把所有的值进行聚合统计,得到一个结果。诶,所以我们看这样一个定义的话,那我当前行可以作为基准,上下统计一个范围内的值,聚合值,那同样它的下一行是不是也可以在这个范围内上下统计这样一个范围内值啊,哎,所以它相当于是针对每一行都可以计算这样的一个聚合值,这就有点类似于我们是一个滑动窗口一样,只不过滑动它是滑动技术窗口对吧?是按照这个行数每一行一行的往后滑的啊,所以我们可以看到在flink SQ里边,它并没有单独的去定义技术窗口,那技术窗口可以用什么样的方式来实现呢?
02:36
能用标准CQ里开聚来实现。那在一般情况下,如果我们当前这个就是一行一行往后滑的话,一行一行去看当前的这个聚合结果的话,很显然每一行都有对应的一个聚合值得到的结果表。那就会跟原始的表有相同的行数,因为每一行都有一个聚合值嘛啊。
03:01
这样的话就相当于跟我们平常认为的那种窗口聚合不太一样,平常所认为的窗口聚合,它是跟。我们开的时间窗,时间窗口的多少有关的结果,这个行数是跟时间窗口相关的,而现在呢,只跟之前的行数相关。那比如说我们这里。可以,呃,看到啊,就是比方说我们可以以每一行数据为基准,计算它之前的一个小时内的所有数据的平均值啊,那这个看起来这也又像是一个时间窗口一样啊,就是基于当前这个行可以开一个over window,也是基于时间去定义的,另外呢,也可以基于行数去定义,就是计算它之前的十个数的平均数,诶,那这这就是一个标准的计数窗口。所以就相当于是在每一行上打开了一个窗户,所谓的开窗函数指的也就是这个啊,在him上啊,其他的一些这个。
04:01
类似于CQ的用法里边我们都可以看到类似开窗函数的定义,那开窗函数的聚合跟之前两种聚合呢,它其实是有本质的不同的,之前我们介绍的都是多对一,而现在呢,就是一一对一,或者说是多对多的这样一个关系了。那在。CQ里边怎么样用这样的一个开窗函数呢?使用方式啊,语法跟标准CQ里边都一样,使用over子句,哎,所以所谓的开窗聚合有时候也叫做over聚合,它的基本语法就是这样的select,哎,然后我们要使用一个聚合函数,然后直接over。Over子句就用在这儿了,后边呢就是当前开窗函数这个窗口的定义。怎么定义呢?首先可以有一个ition b分区啊,那这个是可选的,也就是说指定当前分区的舰,类似于group by,我们指定的那个键,按照什么样的字段去进行分组的聚合统计,分区的聚合统计。
05:08
后面呢,跟着一个这个后要是时间当fli的照行排序的这样的一个开窗许可。然后接下来是开窗范围,开窗范围的话,这就分为两种定义方式了。我们可以看到开窗范围一种定义方式是所谓的。范围间隔。而它范围间隔,那就是。相当于定义的是之前的一段时间啊,那我们标准的定义形式就是。这个范围开窗的范围是什么呢?就是between什么什么preing,它之前是多少,然后and什么什么啊,那正常情况我们想到应该是and什么什么,然后截止到后边多少,但是要注意当前的flink CQ呢,只能。
06:01
开到当前的好。不支持开到当前行以后,这个其实也很好理解,因为我们前面说了,当前flink我们是一个流式处理,流式数处理,当前的这个表里面的行是一行一行来的,不停往后追加的。而且我们是要按照时间属性字段进行排序,Order by,诶,那所以这个过程很明显。先来的数据应该放在上边,后来的数据追加到它的下边,那接下来如果说我们统计的这个范围,你要统计当前行以下的数据的话,那岂不就是要统计。当前时间点之后,未来要到来的数据吗?那现在还没来啊,当然就统计不到了,那所以当前是只支持统计到当前。也就是只能相当于是基于当前航去取之前的多少数据,那之前的多少数据呢,就可以基于时间,也可以基于数量,类似于时间窗口和技术窗口,那如果基于时间的话,就是所谓的范围间隔,它的定义就是range,我们可以看到就是。
07:13
当前range between,然后interval e小时,然后pre and current,这就表示开窗范围是选取当前航之前一小时之内的数据。开窗,然后进行统计聚合,那另外还可以指定行间隔,类似于技术窗口,怎么样定义呢?它定义的是Rose between Rose between 5and current,那就相当于是统计当前行以及之前的五行数据,那当然了,就是一共六条数据进行统计。接下来我们可以在代码里边看一下具体的应用。代码里边的话,我们还是在之前的这段代码下边直接追加一个啊,这个其实跟标准的这个窗口聚合已经有所不同了,我们直接写成第四个部分,这个叫开窗聚合。
08:07
也就是over。Over子句。使用over子句的over句合啊,那这里我们可以直接table env写一个query啊,同样这里我们还是select user,那我们想要统计什么呢?可以想一个具体的需求,比如说我们就可以直接统计当前。当前所有数据范围内啊,我们之前都已经有时间窗口了,现在干脆来一个类似于技术窗口的,呃,这样的一个需求吧,我们就统计每个用户。当前这次访问以及之前三次访问的平均时间戳啊,那某种意义上也能。代表当前用户的一个活跃程度吧,那就是最近到底有多活跃啊,那所以我们是这样的一个求平均值的统计的思路啊,那所以当前我们可以直接。
09:04
首先有用户嘛,那就是user user username,然后接下来那就需要。得有一个聚合的结果了啊,那这个聚合结果非常简单,Avg。对于当前的TS,我我们之前不是有这个,呃,时间戳这个字段是保留在里边的吗?长整形的这个字段保留在里边了,我们可以直接对于TS做一个聚合AG求平均数,然后另外呢,后面就是直接over了。接下来over里边这个描述,这是当前开窗函数的一个定义的核心啊,那首先我们知道现在是要分区的,因为我们是有这个,就是基于用户去做划分的嘛,那username肯定要出现在这里,所以是。User。
10:03
呃,这这里注意在当前这个over子句里边。不需要任何的逗号啊,所有这个语法是一气呵成啊,直接在后面空格就可以了,所以接下来直接order by。哎,只能是当前的时间属性字段ET。然后再接下来是啊,既然是技术窗口,那就是。翡翠。接下来是之前的三行数据,那就是三,然后。And。Current肉。诶,这样的话,我们就把当前的这一个,呃,开窗函数的这个over窗口这个子句定义好了,这里还需要注意的是。
11:06
我们想要把当前得到这个结果,还要对应的给他指定一个字段名列名的话,那后面当然是需要有一个as这样的关键字了。S,比方说我们这个就叫做AV GPS,那这样的话,我们想要的东西就都已经拿出来,那后面当然就是。From哪张表了当前的click?这样就把对应的这一个开窗聚合的过程写出来了。我们可以把这个叫做。Over window result。接下来我们同样可以把它转换成流,做一个控制台的打印输出。其实前面这个我们都可以注掉了。只看一下当前。Over的这个结果是什么样就可以了。接下来我们重新运行一下,看一看。跟我们之前所有的窗口聚合有什么不同?
12:04
我们可以看到当前同样还是所有的元素都是追加,当前是一个都是追加上去的,加I来到这里,我们看到首先第一条数据来了之后,哎,那只有他嘛,他之前没有数据,当然就是自己了,所以我们看啊Mary后边,因为Mary只有两条数据,所以当前就没有任何的。哦,这里第二条数据还是有意义的,它是11秒的时候传进来的,所以我们看到相当于求了第二条数据和第一条数据的一个平均时间戳,所以我们知道两条相加,诶,得到这个平均数是六秒。那同样对应的这个Bob,我们看到Bob第1BOB的数据最多嘛,我们就看它,它的第一条数据是两秒,诶这个不变,第二条数据四秒来了之后,诶一平均是三秒,第三条数据五秒又来之后,诶一平均是3.666秒啊。那接下来再来下一条数据是七七的话,我们知道就相当于是24574条数据要做平均,我们看得到的是一个。
13:11
4500,诶,那那这个4500,注意是四条数据的平均是要包含当前这条数据的,另外如果再来一条八的话,我们会看到它瞬间比之前就这个平均数就大了好多,变成了6000,为什么呢?因为它当前就不再去选取最初的第一条数据了,它是4578这四条数据的平均数,所以刚好是六秒。这就是关于over窗口的使用,开窗聚合在很多场景里边,Over窗口还是非常有用的,而且我们也可以用它完整的实现之前data stream API里面的技术窗口的功能。我们这里的这个例子相对来讲是比较简单的over窗口的用法,诶那我们会发现这里边我们只定义了基于这个over窗口的一种聚合函数,那有时候我们想到,那如果我想要调用多个聚多个聚合函数,基于一个同样定义的over窗口,诶那怎么样去定义呢?当然你可以就是重复的再把这个COPY1份,然后再再去后面追加一个字段,这样也是可以的,那有点麻烦啊,那另外还有一种比较简单的写法,我们可以看到。
14:28
可以直接这样去写,就是在后边单独的把这个window定义出来啊,就是用window关键字window w定义一个W,这个W后面,这就相当于是我们over窗口的这个定义的过程,把这个完整的把这整个这一部分把它声明成W,那在前面呢,那就可以用W来替代它,相当于给这个over窗口的定义。设置了一个别名啊,所以比方说我们可以直接count URL后面还可以max,然后统计这个URL的一个字符,字符串的这个啊,字符的长度,然后同样也是这样的话,我们就不需要把对应同样的这个窗口声定义在这两次。
15:15
这两种方式都是可以去选择的,这就是关于over窗口的用法。
我来说两句