大家好,我是老杨。今天我们来学习一下FlinkSQL中的WindowTopN操作。WindowTopN定义(支持Streaming):WindowTopN是一个特殊的TopN,它的返回结果是每个窗口中的N个最小值或最大值。应用场景:萌辉朋友会问,我有TopN为什么还要WindowTopN?还记得上面介绍TopN的时候,会有中间结果,所以会有回撤数据吗?WindowTopN不会有回撤数据,因为WindowTopN实现在窗口结束时输出最终结果,不会产生中间结果。并且注意因为是对窗口的操作,WindowTopN会在窗口结束的时候自动清除State。SQL语法标准:SELECT[column_list]FROM(SELECT[column_list],ROW_NUMBER()OVER(PARTITIONBYwindow_start,window_end[,col_key1...]ORDERBYcol1[asc|desc][,col2[asc|desc]...])ASrownumFROMtable_name)--windowingTVFWHERErownum<=N[ANDconditions]实际案例:取当前分钟搜索关键词的前10条词条数据。输入表字段:--字段名备注--keysearchkeyword--name搜索热度名称--search_cnt热搜消费热度(比如3000)--timestamp消费入口timestampCREATETABLEsource_table(nameBIGINTNOTNULL,search_cntBIGINTNOTNULL,keyBIGINTNOTNULL,row_timeAScast(CURRENT_TIMESTAMPastimestamp(3)),WATERMARKFORrow_timeASrow_time)WITH(...);--输出表字段:--字段名备注--keysearchkeyWord--name搜索热度名称--search_cnt热搜消费热度(比如3000)--window_start窗口开始时间戳--window_end窗口结束时间戳CREATETABLEsink_table(keyBIGINT,nameBIGINT,search_cntBIGINT,window_startTIMESTAMP(3),window_endTIMESTAMP(3))WITH(...);--处理sql:INSERTINTOsink_tableSELECTkey,name,search_cnt,window_start,window_endFROM(SELECTkey,name,search_cnt,window_start,window_end,ROW_NUMBER()OVER(PARTITIONBYwindow_start,window_end,关键顺序BYsearch_cntdesc)ASrownumFROM(SELECTwindow_start,window_end,key,name,max(search_cnt)assearch_cnt--窗口tvf写入FROMTABLE(TUMBLE(TABLEsource_table,DESCRIPTOR(row_time),INTERVAL'1'MINUTES))GROUPBYwindow_start,window_end,key,name))WHERErownum<=100输出结果:+I[keyword1,entry1,8670,2021-1-28T22:34,2021-1-28T22:35]+I[keyword1,entry2,6928,2021-1-28T22:34,2021-1-28T22:35]+I[关键字1,条目3,1735,2021-1-28T22:34,2021-1-28T22:35]+I[关键字1,条目4,7287,2021-1-28T22:34,2021-1-28T22:35]...可以看出结果符合预期,并没有收回数据的SQL语义。数据来源:数据来源为最新词条下搜索词的搜索热度数据。数据在Kafka消费后,根据窗口聚合的key,通过哈希分发策略,将数据发送给下游的窗口聚合算子。窗口聚合算子:进行窗口聚合计算,随着时间的推移,计算出窗口聚合结果,发送给下游的窗口排序算子。Windowsortingoperator:这个算子其实就是一个windowoperator,只不过这个windowoperator为每个Key维护了一个TopN列表数据,接收上游发来的window结果数据并进行排序,随着时间的推移,window结束,将排序后的结果输出给下游的数据汇算子。Datasink:接收到上游数据后,输出到外部存储引擎。
