KDB滚动总和
KDB rolling sum
我有一个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
我可能误解了你的问题.. 所以你想要匹配 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.传递table和table.
的每一行
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]);
};
通过每个权限更新 table(/)
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]
这应该可以满足您的要求:
//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
这可能有用,虽然有点难看;
`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 中聚合数据。可能有一种方法可以隐式执行此操作,但我现在不会想到。
如果行是按时间顺序排列的,则不需要对 table 进行排序:by 子句将执行您想要的操作。
- 使用
update
通过date
和ts
计算cumsum
- Select
last
cumsum
的值 date
、ts
和 sym
- 删除密钥
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)]
我有一个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
我可能误解了你的问题.. 所以你想要匹配 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.传递table和table.
的每一行 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]);
};
通过每个权限更新 table(/)
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]
这应该可以满足您的要求:
//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
这可能有用,虽然有点难看;
`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 中聚合数据。可能有一种方法可以隐式执行此操作,但我现在不会想到。
如果行是按时间顺序排列的,则不需要对 table 进行排序:by 子句将执行您想要的操作。
- 使用
update
通过date
和ts
计算cumsum
- Select
last
cumsum
的值date
、ts
和sym
- 删除密钥
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)]