问题描述
id date name order
34 2020.01.20 John 10
23 2020.01.20 John -20
21 2020.01.20 John 30
43 2020.01.20 John -400
44 2020.01.20 Dan -6483
22 2020.01.20 Dan 8796
可以如下创建样本表:
t:([]id:(34,23,21,43,44,22); date:(2020.01.20; 2020.01.20; 2020.01.20; 2020.01.20; 2020.01.20; 2020.01.20); name:(`John`John`John`John`Dan`Dan); order:(10,-20,30,-400,-6483,8796));
我希望以下格式的任何给定date
和name
都可能有订单的所有子集。现在,下面的order
列是order
和所有id
的{{1}}值的总和。
ids
解决方法
不确定这是否是最佳解决方案,但是下面的代码片段将满足您的需求:
orderMap: (!) . t`id`order;
subsets: ungroup
update ids: {x where each (count[x]-1){x cross 01b}/01b} each ids from
select ids: id by name from t;
t: ej[`name;t;subsets];
t: delete from t where id in' ids;
t: update order: order + sum each orderMap@/:ids from t;
t
为了保持一致,将ids列创建为整数列表的列表,并使用空数组`long$()
代替0n
更详细:
-
orderMap: (!) . t`id`order
给出ID到顺序的映射。在这里,我假设id
是唯一的。 -
subsets
是分配给名称的name
和id
子集的表。{(count[x]-1){x cross 01b}/01b}
返回有助于包含子集的“ include”标志,例如0000b,1000b,0100b,...
。整数二进制表示可以更有效地完成。 -
ej[`name;t;subsets]
-按名称连接具有ID子集的原始表。 -
delete from t where id in' ids
删除id
子集中包含ids
的行。 -
update order: order + sum each orderMap@/:ids from t
通过使用id
来总结ids
和orderMap
'子集的顺序
尽管您似乎排除了这种额外的组合(这可以在需要时可以将其排除在外),但这可以使您成为其中的一部分:
q)comb:{$[type b:(count[a:x except y]-1)(01b cross)/01b;(`long$();a);a where each b]};
q)update sum each order from ungroup ungroup select id,order:(order,/:'order i?comb[i]each i),ids:id i?comb[i]each i by date,name from t
date name id order ids
---------------------------------
2020.01.20 Dan 44 -6483 `long$()
2020.01.20 Dan 44 2313,22
2020.01.20 Dan 22 8796 `long$()
2020.01.20 Dan 22 2313,44
2020.01.20 John 34 10 `long$()
2020.01.20 John 34 -390,43
2020.01.20 John 34 40,21
2020.01.20 John 34 -360 21 43
2020.01.20 John 34 -10,23
2020.01.20 John 34 -410 23 43
2020.01.20 John 34 20 23 21
2020.01.20 John 34 -380 23 21 43
2020.01.20 John 23 -20 `long$()
2020.01.20 John 23 -420,43
...