KDB/Q-sql 输出中的动态分组和连接列
KDB/Q-sql Dynamic Grouping and con-canting columns in output
我有一个 table,我必须在其中对动态列执行分组并执行聚合,结果将是列值连接分组 table 和对用户提供的 col 的聚合。
例如:
g1 g2 g3 g4 col1 col2
A D F H 10 20
A E G I 11 21
B D G J 12 22
B E F L 13 23
C D F M 14 24
C D G M 15 25
如果我需要对 col1 输出执行 g1、g2、g4 和 avg 聚合应该像这样
filed val
Avg[A-D-H-col1] 10.0
Avg[A-E-I-col1] 11.0
Avg[B-D-J-col1] 12.0
Avg[B-E-L-col1] 13.0
Avg[C-D-M-col1] 14.5
如果我的按列分组使用 q-sql
固定,我可以执行此操作
t:([]g1:`A`A`B`B`C`C;g2:`D`E`D`E`D`D;g3:`F`G`G`F`F`G;g4:`H`I`J`L`M`M;col1:10 11 12 13 14 15;col2:20 21 22 23 24 25)
select filed:first ("Avg[",/:(({"-" sv x} each string (g1,'g2,'g4)),\:"-col1]")),val: avg col1 by g1,g2,g4 from t
我想使用相同的函数查询,这意味着我想要一个函数,它将按列分组的列表、要执行的聚合以及列名和table名称作为输入和输出,就像上面的查询一样。我可以通过轻松使用动态列来执行分组,但无法在字段中进行 con-cat。函数签名将是这样的
好玩{[glist;聚合; col,t] .. ;... }[g1
g2g4;
avg;col1,
t]
请帮我把上面的查询变成动态的。
您可以尝试以下功能:
specialGroup: {[glist;agg;col;table]
res: ?[table;();{x!x}glist; enlist[`val]!enlist(agg;col)];
aggname: string agg;
aggname: upper[1#aggname], 1_aggname;
res: ![res;();0b;enlist[`filed]!enlist({(y,"["),/:("-"sv/:string flip x),\:"]"};enlist,glist,enlist[enlist col];aggname)];
res
};
specialGroup[`g1`g2`g4;avg;`col1;t]
specialGroup
首先将值聚合到 val
列中。并在分组后填充 filed
列。这有助于避免生成 filed
个重复项并选择其中的第一个。
如果您将 Anton 的代码修改为此,它将动态更改输出
specialGroup: {[glist;agg;col;table]
res: ?[table;();{x!x}glist; enlist[`val]!enlist(agg;col)];
res: ![res;();0b;enlist[`filed]!enlist({(@[string[y];0;upper],"["),/:("-"sv/:string flip x),\:"]"}[;agg];enlist,glist,enlist[enlist col])];
res
};
由于生成该字符串的代码部分位于另一个函数中,因此您需要将 agg 参数传递给内部函数。
我有一个 table,我必须在其中对动态列执行分组并执行聚合,结果将是列值连接分组 table 和对用户提供的 col 的聚合。
例如:
g1 g2 g3 g4 col1 col2
A D F H 10 20
A E G I 11 21
B D G J 12 22
B E F L 13 23
C D F M 14 24
C D G M 15 25
如果我需要对 col1 输出执行 g1、g2、g4 和 avg 聚合应该像这样
filed val
Avg[A-D-H-col1] 10.0
Avg[A-E-I-col1] 11.0
Avg[B-D-J-col1] 12.0
Avg[B-E-L-col1] 13.0
Avg[C-D-M-col1] 14.5
如果我的按列分组使用 q-sql
固定,我可以执行此操作t:([]g1:`A`A`B`B`C`C;g2:`D`E`D`E`D`D;g3:`F`G`G`F`F`G;g4:`H`I`J`L`M`M;col1:10 11 12 13 14 15;col2:20 21 22 23 24 25)
select filed:first ("Avg[",/:(({"-" sv x} each string (g1,'g2,'g4)),\:"-col1]")),val: avg col1 by g1,g2,g4 from t
我想使用相同的函数查询,这意味着我想要一个函数,它将按列分组的列表、要执行的聚合以及列名和table名称作为输入和输出,就像上面的查询一样。我可以通过轻松使用动态列来执行分组,但无法在字段中进行 con-cat。函数签名将是这样的
好玩{[glist;聚合; col,t] .. ;... }[g1
g2g4;
avg;col1,
t]
请帮我把上面的查询变成动态的。
您可以尝试以下功能:
specialGroup: {[glist;agg;col;table]
res: ?[table;();{x!x}glist; enlist[`val]!enlist(agg;col)];
aggname: string agg;
aggname: upper[1#aggname], 1_aggname;
res: ![res;();0b;enlist[`filed]!enlist({(y,"["),/:("-"sv/:string flip x),\:"]"};enlist,glist,enlist[enlist col];aggname)];
res
};
specialGroup[`g1`g2`g4;avg;`col1;t]
specialGroup
首先将值聚合到 val
列中。并在分组后填充 filed
列。这有助于避免生成 filed
个重复项并选择其中的第一个。
如果您将 Anton 的代码修改为此,它将动态更改输出
specialGroup: {[glist;agg;col;table]
res: ?[table;();{x!x}glist; enlist[`val]!enlist(agg;col)];
res: ![res;();0b;enlist[`filed]!enlist({(@[string[y];0;upper],"["),/:("-"sv/:string flip x),\:"]"}[;agg];enlist,glist,enlist[enlist col])];
res
};
由于生成该字符串的代码部分位于另一个函数中,因此您需要将 agg 参数传递给内部函数。