kdb 如何在 select 中有一个条件和
kdb how to have a conditional sum in select
我怎样才能在 kdb 中有条件求和,类似于下面的 sql 查询
Select sum(qty > 0, qty, 0) as buy, sum(qty < 0, qty, 0) as sell from trades
我正在寻找一种无需任何 where 子句即可执行此操作的方法。
您可以在 select 语句中使用内联 lambda 函数来实现此目的:
q)trades:([]sym:`a`b`c`d`e`f`g;qty:-34 -27 -11 50 19 -30 1)
q)select buy:sum {x where 0<x}[qty], sell:sum {x where 0>x}[qty] from trades
buy sell
--------
70 -102
更好的方法(有条件):
q)select buy:sum ?[qty>0;qty;0], sell:sum ?[qty<0;qty;0] from trades
buy sell
--------
70 -102
使用 'min' 和 'max' 运算符:
q)select buy:sum qty|0f,sell:sum qty&0f from trades
buy sell
--------
70 -102
我会遵循@davidcrossey 提出的第一种方法,但会稍微简化代码并删除匿名函数:
select buy: sum qty where qty > 0, sell: sum qty where qty < 0 from trades
这个查询是可取的,因为 ?[;;]
工作更慢并且消耗更多 space (~ 2 次)。 min/max
方法可能更快,但也会消耗 x2 space。您可以使用下一个代码作为性能测试,\ts
returns time space
被查询使用
trades: enlist[`qty]!enlist -50 + 1000000?100;
\ts select buy: sum qty where qty > 0, sell: sum qty where qty < 0 from trades
// returns 43 8389424
\ts select buy:sum ?[qty>0;qty;0], sell:sum ?[qty<0;qty;0] from trades
// returns 68 17826560
\ts select buy:sum qty|0f,sell:sum qty&0f from trades
// returns 39 16777856
在这种情况下,<
& >
充当向量条件运算符,因此传递完整的列有效。 但是,有些情况下函数需要输入作为原子,在这种情况下,可以使用 each
。
q)trades:([]sym:`a`b`c`d`e`f`g;qty:-34 -27 -11 50 19 -30 1)
q)select buy:sum qty where {0<x}each qty, sell:sum qty where {0>x} each qty from trades
buy sell
--------
70 -102
您现在可以将 {0<x}
替换为一些以原子为参数的更复杂的函数,它应该可以正常工作。
我怎样才能在 kdb 中有条件求和,类似于下面的 sql 查询
Select sum(qty > 0, qty, 0) as buy, sum(qty < 0, qty, 0) as sell from trades
我正在寻找一种无需任何 where 子句即可执行此操作的方法。
您可以在 select 语句中使用内联 lambda 函数来实现此目的:
q)trades:([]sym:`a`b`c`d`e`f`g;qty:-34 -27 -11 50 19 -30 1)
q)select buy:sum {x where 0<x}[qty], sell:sum {x where 0>x}[qty] from trades
buy sell
--------
70 -102
更好的方法(有条件):
q)select buy:sum ?[qty>0;qty;0], sell:sum ?[qty<0;qty;0] from trades
buy sell
--------
70 -102
使用 'min' 和 'max' 运算符:
q)select buy:sum qty|0f,sell:sum qty&0f from trades
buy sell
--------
70 -102
我会遵循@davidcrossey 提出的第一种方法,但会稍微简化代码并删除匿名函数:
select buy: sum qty where qty > 0, sell: sum qty where qty < 0 from trades
这个查询是可取的,因为 ?[;;]
工作更慢并且消耗更多 space (~ 2 次)。 min/max
方法可能更快,但也会消耗 x2 space。您可以使用下一个代码作为性能测试,\ts
returns time space
被查询使用
trades: enlist[`qty]!enlist -50 + 1000000?100;
\ts select buy: sum qty where qty > 0, sell: sum qty where qty < 0 from trades
// returns 43 8389424
\ts select buy:sum ?[qty>0;qty;0], sell:sum ?[qty<0;qty;0] from trades
// returns 68 17826560
\ts select buy:sum qty|0f,sell:sum qty&0f from trades
// returns 39 16777856
在这种情况下,<
& >
充当向量条件运算符,因此传递完整的列有效。 但是,有些情况下函数需要输入作为原子,在这种情况下,可以使用 each
。
q)trades:([]sym:`a`b`c`d`e`f`g;qty:-34 -27 -11 50 19 -30 1)
q)select buy:sum qty where {0<x}each qty, sell:sum qty where {0>x} each qty from trades
buy sell
--------
70 -102
您现在可以将 {0<x}
替换为一些以原子为参数的更复杂的函数,它应该可以正常工作。