如何让Flink Table API中BIGINT字段的avg/stddevPop返回Double类型?
Flink Table API:BIGINT字段聚合返回Double类型的解决方法
可以实现,以下是两种常用的处理方式:
方法一:聚合前转换字段类型
在调用聚合函数前,用cast()将BIGINT类型的pkts_from_src转为DOUBLE类型,这样avg和stddevPop的计算会基于Double精度,最终返回Double类型。这种方式能避免整数聚合时的精度丢失(比如平均值为小数时不会被截断)。
修改后的代码示例:
Table windowedTable = inputTable .window(Tumble.over(lit(5).seconds()).on($("ts")).as("w")) .groupBy($("w"), $("src_ip")) .select($("w").start().as("window_start"), $("src_ip"), $("pkts_from_src").cast(DataTypes.DOUBLE()).avg().as("pkts_from_src_mean"), $("pkts_from_src").cast(DataTypes.DOUBLE()).stddevPop().as("pkts_from_src_stddev") ); windowedTable.execute().print();
方法二:聚合后转换结果类型
如果不需要改变聚合计算的精度,只是希望最终结果转为Double,可以直接对聚合后的结果调用cast()。这种方式先按BIGINT类型完成聚合(结果为Long),再转换为Double。
修改后的代码示例:
Table windowedTable = inputTable .window(Tumble.over(lit(5).seconds()).on($("ts")).as("w")) .groupBy($("w"), $("src_ip")) .select($("w").start().as("window_start"), $("src_ip"), $("pkts_from_src").avg().cast(DataTypes.DOUBLE()).as("pkts_from_src_mean"), $("pkts_from_src").stddevPop().cast(DataTypes.DOUBLE()).as("pkts_from_src_stddev") ); windowedTable.execute().print();
注意事项
- 两种方法的核心都是利用Flink Table API的
cast()函数,指定目标类型为DataTypes.DOUBLE()。 - 若需要保留聚合计算的小数精度(比如平均值非整数的场景),优先选择方法一,因为方法二在聚合阶段会截断小数部分,再转Double也无法恢复精度。
内容的提问来源于stack exchange,提问作者Charles Ju
相关产品推荐
相关产品推荐

