如何在Kdb+的wj函数中对左表列执行聚合操作?
解决Kdb+中wj聚合无法引用左表列的问题
在Kdb+的wj(窗口连接)函数中,聚合函数的作用域默认仅包含**右表(q)**的列,因此直接引用左表(t)的weightLeft会因找不到列而报错。要让左表列参与聚合,可通过以下两种方式实现:
方案一:先聚合右表,再与左表列运算
如果左表列是每行固定的标量(如本例的weightLeft),聚合逻辑可拆解为「右表聚合结果 × 左表列值」,这种方式效率最高:
t:([]sym:3#`ibm;time:10:01:01 10:01:04 10:01:08;price:200 201 205;weightLeft:3 4 5); price:101 103 103 104 104 107 108 107 108; weight:10 20 30 10 20 30 10 20 30; q:([]sym:`ibm; time:10:01:01+til 9; price:price; weight:weight); f:`sym`time; w:-2 1+\:t.time; // 先计算右表窗口内的sum(price) baseResult: wj[w;f;t;(q;(sum;`price))]; // 合并左表weightLeft,计算sum(price * weightLeft) finalResult: update sum_price_weightLeft: sum_price * weightLeft from baseResult;
方案二:逐行处理左表,传递左表列参数
如果需要更复杂的逐行运算(比如左表列与右表列逐行匹配后再聚合),可通过each遍历左表每一行,将当前行的weightLeft作为参数传入聚合逻辑:
t:([]sym:3#`ibm;time:10:01:01 10:01:04 10:01:08;price:200 201 205;weightLeft:3 4 5); price:101 103 103 104 104 107 108 107 108; weight:10 20 30 10 20 30 10 20 30; q:([]sym:`ibm; time:10:01:01+til 9; price:price; weight:weight); // 遍历左表每一行,单独处理窗口聚合 finalResult: t, (each[{ row: x; // 生成当前行的时间窗口 window: -2 1 +\: row.time; // 查询右表中符合条件的数据并计算聚合 agg: select sum_price: sum price, sum_price_weightLeft: sum price * row.weightLeft from q where sym=row.sym, time within window; agg }] each t);
两种方案都能实现weightLeft参与聚合的需求,方案一更适合简单的标量运算场景,方案二适用于复杂的逐行匹配聚合场景。
内容的提问来源于stack exchange,提问作者H42
相关产品推荐
相关产品推荐

