KQL make-series算子为何将部分real类型平均值转换为字符串?
为什么KQL的
make-series结果中部分数值是字符串类型? 这个现象其实和浮点数的二进制精度限制以及Kusto的JSON序列化规则直接相关,我来拆解一下:
1. 浮点数的精度本质问题
你用的real类型是64位双精度浮点数,它能精确表示的十进制小数是有限的——只有那些可以表示为x/(2^n)的数(比如0.5=1/2、0.25=1/4)才能被精确存储。像0.1、0.35这类小数,在二进制里是无限循环的,存储时会有微小的精度损失(比如50.35实际存储为50.349999999999994)。
2. Kusto的JSON序列化逻辑
为了避免精度丢失,Kusto在序列化JSON时会做一个判断:
- 如果浮点数的十进制表示可以和其二进制存储值精确对应,就直接序列化为数字类型(比如你的结果里的
50.5、50.8); - 如果存在精度损失(即实际存储的二进制值和原始十进制值有偏差),就会将其序列化为字符串,保留最精确的表示(比如
"50.349999999999994")。
这就是为什么你看到数组里既有数字又有字符串的原因——不是make-series输出了混合类型,而是JSON序列化时的策略导致的。
解决办法:统一输出数字类型
如果你的业务场景不需要极致的精度,可以通过四舍五入让数值变成能被精确表示的形式,这样Kusto就会统一序列化为数字类型:
let data=datatable(timestamp: datetime, metric: real) [ datetime(2020-01-01 00:00:00), 50.3, datetime(2020-01-01 00:10:00), 50.4, datetime(2020-01-01 00:20:00), 50.5, datetime(2020-01-01 00:30:00), 50.6, datetime(2020-01-01 00:40:00), 50.7, datetime(2020-01-01 00:50:00), 50.8, datetime(2020-01-01 01:00:00), 50.9, datetime(2020-01-01 01:10:00), 50.01, datetime(2020-01-01 01:20:00), 50.08, datetime(2020-01-01 01:30:00), 50.13, datetime(2020-01-01 01:40:00), 50.65, datetime(2020-01-01 01:50:00), 50.99 ]; data | make-series avg_metric = round(avg(metric), 2) on timestamp step 15m;
这里用round(avg(metric), 2)把平均值四舍五入到两位小数,处理后的结果会被Kusto序列化为纯数字类型的数组。
内容的提问来源于stack exchange,提问作者Klare Data
相关产品推荐
相关产品推荐

