首页 文章

KDB滚动总和

提问于
浏览 1808
0

我有一张 table

t:flip `date`sym`ts`qty!(`d1`d1`d1`d1`d1`d1`d2;`s1`s1`s2`s1`s1`s2`s1;`t1`t1`t2`t3`t4`t5`t1;-100 -100 200 200 500 -300 -400)

date    sym   ts     qty
d1       s1   t1    -100
d1       s1   t1    -100
d1       s2   t2     200
d1       s1   t3     200
d1       s1   t4     500
d1       s2   t5    -300
d2       s1   t1    -400

而且我希望在同一天的每个时间点获得每个sym的累积总和数量

date    sym   ts     qty   cumsum
d1       s1   t1    -100     -200 // -100 - 100
d1       s2   t2     200      200 //  200
d1       s1   t3     200        0 // -100 -100 + 200
d1       s1   t4     500      500 // -100 -100 + 200 + 500
d1       s2   t5    -300     -100 //  200 - 300
d2       s1   t1    -400     -400 // -400 (date is d2)

我试过用

select sums qty by date, ts, sym from t

但是有了这个,我只设法将具有相同键 date ts`sym的行折叠成一个列表,但它并没有给我一个滚动的总和 . 有什么建议?

编辑:所以,基本上我想附加一个列,显示我将从此查询中获得的值

select sum qty from t where sym =`symbol_of_this_row, ts <= ts_of_this_row, date = _date_of_this_row

4 回答

  • 2

    我可能误解了你的问题..所以你想要匹配 date sym`timestamp的行的累积总和,是吗?

    这个怎么样:

    t: update cumsum:sums qty by date, sym, ts from t
        // for the sake of 'pretty view' sort by `date`sym`ts 
        `date`sym`ts xasc t
    

    编辑:我相信你可以通过功能更新让它更漂亮(http://www.timestored.com/kdb-guides/functional-queries-dynamic-sql)我只是自己写了一些函数来向你展示基本的想法 . 1.通过表和每行表 .

    temp:{[idx; tbl]
             row: first select from tbl where i = idx;
             : last update cumulative:sums qty from (select from tbl where date=row[`date], sym=row[`sym], ts<=row[`ts]);
             };
    
    • 通过每个权利更新表格(/)
    temp2:{[tbl; idx]
        row: first select from tbl where i = idx;
        :tbl lj (`date`sym`ts xkey enlist last update cumulative:sums qty from  (select from tbl where date=row[`date],sym=row[`sym],ts<=row[`ts]));
        };
    

    对于#1,你可以调用类似的东西:

    tbl: {: temp[y; x] }[; tbl] each til count tbl
    

    对于#2,你可以打电话给:

    tbl: temp2/[tbl; til count tbl]
    
  • 1

    这可能有用,虽然有点难看;

    `date`ts xasc 0! / sort and unkey
        update cumsum:sums qty by date, sym from 
            select sum qty by date, sym, ts from t
    

    哪个产生;

    date sym ts qty  cumsum
    -----------------------
    d1   s1  t1 -200 -200  
    d1   s2  t2 200  200   
    d1   s1  t3 200  0     
    d1   s1  t4 500  500   
    d1   s2  t5 -300 -100  
    d2   s1  t1 -400 -400
    

    注意第一行中的数量与您的示例不同 . 那是因为我必须在运行累积和之前聚合相同ts中的数据 . 可能有一种方法可以隐含地执行此操作,但现在不会发现它 .

  • 1

    如果行按时间顺序排列,则无需对表进行排序:by子句将执行您想要的操作 .

    • 使用 updatedatets 计算 cumsum

    • datetssym 选择 last cumsum 的值

    • 删除密钥

    q)0!select last cumsum by date,ts,sym from update cumsum: sums qty by date,sym from t
    date ts sym cumsum
    ------------------
    d1   t1 s1  -200
    d1   t2 s2  200
    d1   t3 s1  0
    d1   t4 s1  500
    d1   t5 s2  -100
    d2   t1 s1  -400
    

    如果你需要参数化任何一个(即传递列名作为参数),你将需要functional forms

    q)u:![t;();`date`sym!`date`sym;(enlist`cumsum)!enlist(sums;`qty)]
    q)0!?[u;();`date`ts`sym!`date`ts`sym;(enlist`cumsum)!enlist(last;`cumsum)]
    

    更多Q for Mortals: §9. Queries

  • 0

    这应该做你想要的:

    //Ascend by date and time to make sure that result sets match
    `date`ts xasc 
        //Compute cumulative sums by date, sym, timestamp
        update sums cumul by date,sym from 
            //Make sure that there is a single qty for each timestamp
            select cumul:sum qty by date,sym,ts from t
    

相关问题