2016-10-01 4 views
3

В SQL агрегированные функции sum (x), avg (x), max (x), min (x) возвращают NULL, когда x пуст или содержит только значения NULL.Получение агрегатных функций для возврата null в KDB

В KDB сумма и avg возвращают ноль, а максимальный и минимальный возврат (+ или -) бесконечности.

Чтобы получить желаемое поведение возвращения нуль я пришел с 2-х вариантов:

(A) Удалите аннулирует, и проверить, если результат пуст, прежде чем агрегирование как обычно

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

(B) Создайте новый агрегат, который проверяет каждый элемент за нуль до накопления.
Обратите внимание, что нам по-прежнему нужно проверить пустой список.

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

Вы можете использовать весь оператор. Также вы можете (возможно, должны) вернуть нуль в зависимости от типа списка.

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, скорости сопоставимы) и использует меньше места.

2

Для min/max вы можете совершать некоторые обманки с добавлением и вычитанием 1 с помощью int/long lists для обеспечения возврата нулей. Это было недавно упомянуто в kxCon2016 Аттилой Vrabecz. Это манипуляция тем, как/где нуль и бесконечность появляются на «числовой строке». Они не очень общие и специфичны для каждой операции:

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 

 Смежные вопросы

  • Нет связанных вопросов^_^