对 KDB/Q-SQL 中的选定行进行条件分组



我有一个要求,我必须执行多个查询并对带有where子句的列执行分组,按列分组是固定的,并且其中条件将在具有可变条件的固定列上执行。只有列名称和聚合类型会有所不同 例如,如果我有表:

k1  k2  val1    val2
1   1   10      30
1   1   20      31
1   2   30      32
2   2   40      33
2   3   50      34
2   4   60      35
2   4   70      36
3   4   80      37
3   5   90      38
3   5   100     39

t:([] k1:1 1 1 2 2 2 2 3 3 3; k2:1 1 2 2 3 4 4 4 5 5; val1:10 20 30 40 50 60 70 80 90 100; val2:31 31 32 33 34 35 36 37 38 39)

我需要执行的查询将类似于

select avg_val1:avg val1 by k1 from t where k2 in 2 3 4
select sum_val1:sum val1 by k1 from t where k2 in 2 3 
select sum_val2:sum val2 by k1 from t where k2 in 2 3 5
select min_val2:min val2 by k1 from t where k2 in 1 2 3 4 5

我想使用函数查询在一次执行中执行这些查询。我试过这个,但无法提出正确的条件和语法

res:?[t;();(enlist`k1)!enlist`k1;(`avg_val1;`sum_val2)!({$[x; y; (::)]}[1b;(avg;`val1)];{$[x; y; (::)]}[1b; (sum;`val2)])];
k1  avg_val1 sum_val2
1   20.0      94
2   55.0      138
3   90.0      114

而不是把 1b 放在条件中,我想像这样放真实条件:

res:?[t;();(enlist`k1)!enlist`k1;(`avg_val1;`sum_val2)!({$[x; y; (::)]}[(in;`k2;2 3 4i);(avg;`val1)];{$[x; y; (::)]}[(in;`k2;2 3i); (sum;`val2)])];

但它会给出"类型"错误,因为查询将是 k1 的第一个组,而 k2 将是列表。所以条件也不对。

我想知道什么是最好的解决方案。也许可以有更好的方法来解决相同的问题。 请帮助我。

谢谢。

向量条件 (?( 运算符可以让你更接近你想要的。

给定您的桌子

t:([] k1:1 1 1 2 2 2 2 3 3 3; k2:1 1 2 2 3 4 4 4 5 5; val1:10 20 30 40 50 60 70 80 90 100; val2:31 31 32 33 34 35 36 37 38 39)
k1 k2 val1 val2
---------------
1  1  10   31  
1  1  20   31  
1  2  30   32  
2  2  40   33  
2  3  50   34  
2  4  60   35  
2  4  70   36  
3  4  80   37  
3  5  90   38  
3  5  100  39  

例如,您可以更新val1列以在条件不成立的地方保存 null 值

update val1:?[k2 in 2 3 4;val1;0N] from t
k1 k2 val1 val2
---------------
1  1       31  
1  1       31  
1  2  30   32  
2  2  40   33  
2  3  50   34  
2  4  60   35  
2  4  70   36  
3  4  80   37  
3  5       38  
3  5       39  

通过更多的工作,您可以获得所需的聚合(注意:聚合函数忽略空值(

select avg ?[k2 in 2 3 4;val1;0N] by k1 from t
k1| x 
--| --
1 | 30
2 | 55
3 | 80

你可以把它包装成一个函数式选择语句,如下所示

?[t;();{x!x}enlist`k1;`avg_val1`sum_val2!((avg;(?;(in;`k2;2 3 4);`val1;0N));(sum;(?;(in;`k2;2 3);`val2;0N)))]
k1| avg_val1 sum_val2
--| -----------------
1 | 30       32      
2 | 55       67      
3 | 80       0       

但是,当您使用不忽略空值的函数时,这可能会中断,例如count.最好在 select 语句中使用 where 运算符:

select avg val1 where k2 in 2 3 4 by k1 from t
k1| x 
--| --
1 | 30
2 | 55
3 | 80
?[t;();{x!x}enlist`k1;`avg_val1`sum_val2!((avg;(`val1;(where;(in;`k2;2 3 4))));(sum;(`val2;(where;(in;`k2;2 3)))))]
k1| avg_val1 sum_val2
--| -----------------
1 | 30       32      
2 | 55       67      
3 | 80       0       

相关内容

  • 没有找到相关文章

最新更新