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

问题描述 投票:3回答:3

任何有关以下的帮助将不胜感激!

我有两个表: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;

这段代码的第四行达到了我想要的两个类别:cl1cl2

table1中,我想命名一个具有类别名称的新列(cl1cl2等),我希望该列中的值是在该列上运行该函数的输出。

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

`cl1`cl2`cl3
kdb
3个回答
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

然后,要创建cat的列,您可以使用类似语法的轴 - 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

要用零填充空值,请使用插入符号 - qazxsw poi

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 从table1到结果的每一行加入

join-each

HTH,肖恩


5
投票

坚持你的方法,你只需要让你的更新语句功能,然后迭代列,如下所示:

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

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

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

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

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

-1
投票

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

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
© www.soinside.com 2019 - 2024. All rights reserved.