功能更新 - 具有动态列的多变量功能

时间:2018-03-05 14:05:22

标签: kdb

非常感谢以下任何帮助!

我有两个表:table1是摘要表,而table2是所有数据点的列表。我希望能够在table2中为table1中的每一行汇总table1:flip `grp`constraint!(`a`b`c`d; 10 10 20 20); table2:flip `grp`cat`constraint`val!(`a`a`a`a`a`b`b`b;`cl1`cl1`cl1`cl2`cl2`cl2`cl2`cl1; 10 10 10 10 10 10 20 10; 1 2 3 4 5 6 7 8); function:{[grpL;constraintL;catL] first exec total: sum val from table2 where constraint=constraintL, grp=grpL,cat=catL}; update cl1:function'[grp;constraint;`cl1], cl2:function'[grp;constraint;`cl2] from table1; 中的信息。

cl1

此代码的第四行达到了我想要的两个类别:cl2table1

cl1中,我想命名一个包含类别名称(cl2`cl1`cl2`cl3 等)的新列,我希望该列中的值为输出从该列上运行该函数。

但是,我有数百个不同的类别,所以不要像第四行那样手动列出它们。我如何传递类别列表,例如下面?

UPDATE Table
SET month_id = (((month_id / 100) + 3) * 100) + (month_id % 100)


--(month_id / 100) will return the year part
--(month_id % 100) will return the month part

3 个答案:

答案 0 :(得分:5)

坚持你的方法,你只需要使你的更新语句起作用,然后像这样迭代列:

{![`table1;();0b;(1#x)!enlist ((';function);`grp;`constraint;1#x)]} each `cl1`cl2

假设你可以修改table1。如果你必须保留原始table1,那么你可以按值传递它,虽然它会消耗更多的内存

{![x;();0b;(1#y)!enlist ((';function);`grp;`constraint;1#y)]}/[table1;`cl1`cl2]

另一种方法是聚合,转移和连接,虽然它不一定是更好的解决方案,因为你得到空值而不是零

a:select sum val by cat,grp,constraint from table2
p:exec (exec distinct cat from a)#cat!val by grp,constraint from a
table1 lj p

答案 1 :(得分:3)

您可以查看几种不同的方法。 最简单的方法是功能更新 - http://code.kx.com/wiki/JB:QforMortals2/queries_q_sql#Functional_update

但是,下面应该更有用,更快更整洁:

您的问题可分为两部分。对于第一部分,您希望通过table2中的grp和约束创建每个类别的总和。至于第二部分,您希望将这些结果(查找)连接到table1的相应记录中。

您可以使用by

创建必要的群组
q)exec val,cat by grp,constraint from table2
grp constraint| val       cat
--------------| ------------------------------
a   10        | 1 2 3 4 5 `cl1`cl1`cl1`cl2`cl2
b   10        | 6 8       `cl2`cl1
b   20        | ,7        ,`cl2

但请注意,这只会在您的选择查询

中创建列的嵌套列表

接下来是sum each群组的cat

q)exec sum each val group cat by grp,constraint from table2
grp constraint|
--------------| ------------
a   10        | `cl1`cl2!6 9
b   10        | `cl2`cl1!6 8
b   20        | (,`cl2)!,7

然后,要创建猫的列,您可以使用类似轴的语法 - http://code.kx.com/wiki/Pivot

q)cats:asc exec distinct cat from table2
q)exec cats#sum each val group cat by grp,constraint from table2
grp constraint| cl1 cl2
--------------| -------
a   10        | 6   9
b   10        | 8   6
b   20        |     7

现在,您可以将此查找表和索引用于table1

中的每一行
q)(exec cats#sum each val group cat by grp,constraint from table2)[table1]
cl1 cl2
-------
6   9
8   6

要用零填充空值,请使用克拉符号 - http://code.kx.com/wiki/Reference/Caret

q)0^(exec cats#sum each val group cat by grp,constraint from table2)[table1]
cl1 cl2
-------
6   9
8   6
0   0
0   0

现在,您可以使用join-each

加入table1中的每一行到您的搜索结果
q)table1,'0^(exec cats#sum each val group cat by grp,constraint from table2)[table1]
grp constraint cl1 cl2
----------------------
a   10         6   9
b   10         8   6
c   20         0   0
d   20         0   0

HTH,肖恩

答案 2 :(得分:-1)

这种方法是传递类别列表的最简单方法

{table1^flip x!function'[table1`grp;table1`constraint;]each x}`cl1`cl2