使聚合函数在KDB中返回null

时间:2016-10-01 19:25:36

标签: sum average min kdb

在SQL中,聚合函数sum(x),avg(x),max(x),min(x) 当x为空或仅包含NULL值时,将返回NULL。

在KDB中,sum和avg返回零,而max和min返回(+或 - )无穷大。

为了获得返回null的所需行为,我提出了两个选项:

(A)删除空值,并在正常聚合之前检查结果是否为空

nsum:{[x] x: x where not null x; $[0=count x; 0N; sum x]}

(B)创建一个新的聚合,在累积
之前检查每个项目是否为null     请注意,我们仍然需要检查一个空列表。

nsum:{[z] $[0=count z; 0N;  {[x;y] $[null x; y; null y; x; x+y]}/ z ]}

是否有比A或B更好(更快和/或更方便)的方式?

方法(B)是否比方法(A)更好地执行?

方法(A)具有为任何聚合函数工作的优点。 方法(B)不适用于"平均",因为没有成对函数 这将产生一个运行平均值(需要知道已经应用了多少项)。

相关问题:检查空列表的速度是否比0=count x更快,例如0= type first x

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用all运算符。您也可以(可能应该)根据列表的类型返回null。

f:{$[all null x;(neg type x)$"";sum x]}
q)f `int$()
0N
q)f 0n 0n 0n 0n
0n

要衡量效果,请使用\t(计时器)或\ts(时间和空格)。 http://code.kx.com/q/ref/syscmds/#t-timer

f1:{$[all null x;(neg type x)$"";sum x]}
fa:nsum:{[x] x: x where not null x; $[0=count x; 0N; sum x]}
fb:{[z] $[0=count z; 0N; {[x;y] $[null x; y; null y; x; x+y]}/[z] ]}

allnull:1000000#0N
withnull:10000000?(1000#0N,til 10)
withoutnull:10000000?10

\ts do[10;f withnull]
612 16777504
..
..

你会发现方法B(fb)是最慢的。 f1比fa更快(除了allnull列表情况,速度可比)并且使用更少的空间。

答案 1 :(得分:2)

对于min / max,你可以通过使用int / long列表添加和减去1来做一些诡计,以确保返回空值。这是最近在kxCon2016由Attila Vrabecz提到的。它是对“数字线”中出现null和无穷大的方式/操作的操纵。虽然它们不是很通用,但具体针对每个操作:

q)a:`int$()
q)b:1 2 3i
q)c:0N 0Ni

q)-1+max 1+a
0N
q)-1+max 1+b
3
q)-1+max 1+c
0N

q)1+min a-1
0N
q)1+min b-1
1
q)1+min c-1
0N