2017-09-07 90 views
1

有没有在kdb中使用查询中的函数的方法。假设我有列KDB在where子句中使用函数

`red`blue`green`yellow`white`purple 

含有任一值0或1代替查询

select where ((red=1) or (green=1)) 

我可以使用像

isRG:{((select green from x)=1) or ((select red from x)=1)} 

的功能来筛选选择的表? 我可以做

f:[select from t] 

,并返回一个true和false列,但我无法弄清楚如何做某事沿

select from t where f[select from t] 

行获得所有条目其中f(x)是真的

+0

J确保评估布尔值或布尔值列表的权利。 – Chromozorz

回答

2

是 - 尽管您不需要将整个表格传递到函数中,但只需输入相关列:

/ define a table 
tbl:flip`red`blue`green`yellow`white`purple!(0N;6)#36?0b; 
    red blue green yellow white purple 
    ---------------------------------- 
    1 0 0  0  1  1  
    1 0 0  0  0  1  
    1 0 0  0  0  0  
    0 0 1  0  0  0  
    1 1 0  0  0  0  
    0 0 0  0  1  0  

/define a function to work on 2 columns - this func simply does or between the columns 
f:{[column1;column2] column1|column2}; 

/use function on 2 columns of table 
select from tbl where f[red;green] 
    red blue green yellow white purple 
    ---------------------------------- 
    1 0 0  0  1  1  
    1 0 0  0  0  1  
    1 0 0  0  0  0  
    0 0 1  0  0  0  
    1 1 0  0  0  0  

主要原则使用功能时,要牢记在选择where子句是:

  • 每一列传入参数,则作为载体
  • 由函数返回的值必须是布尔值的矢量(或布尔等值类型,例如。整数,因为0被认为是错误的)长度相同
1

在这种情况下使用字典似乎更容易;在t使用flip如下:

q)t 
red blue green yellow white purple 
---------------------------------- 
0 1 0  1  1  0 
q) 
q)(key[x:flip[t]] where (raze value x=1))#x 
blue | 1 
yellow| 1 
white | 1 

enlist,如果你想要的结果作为表:

q)enlist (key[x:flip[t]] where (raze value x=1))#x 
blue yellow white 
----------------- 
1 1  1 

另一种可能性是使用functional select和列名的名单中筛选,其中所有值等于1.

1

对此的一些变体可能会很有趣。

foo:{[t;c] t where (|) over flip c#t} 

请注意,c(列名)需要是一个列表。从以前的响应使用TBL:

foo[tbl;`red`blue] 
1

首先,列是布尔向量,这样你就可以在where子句中使用“原始”:

q)tbl 
red blue green yellow white purple 
---------------------------------- 
0 0 1  0  0  0 
1 0 1  1  0  0 
1 0 1  1  1  0 
0 0 0  0  0  0 
0 1 0  0  1  1 
1 0 1  1  0  0 
q)select from tbl where red or green 
red blue green yellow white purple 
---------------------------------- 
0 0 1  0  0  0 
1 0 1  1  0  0 
1 0 1  1  1  0 
1 0 1  1  0  0 

您可以使用自己的函数中where子句?绝对。

q)isRG:{or/[x`red`green]} 
q)isRG tbl 
111001b 
q)select from tbl where isRG tbl 
red blue green yellow white purple 
---------------------------------- 
0 0 1  0  0  0 
1 0 1  1  0  0 
1 0 1  1  1  0 
1 0 1  1  0  0 

超越你的问题,使列名参数的功能,而不是写在Q-SQL where子句中使用函数,使用functional select。在这里,你将你的约束表达为parse tree,例如, (or;`red;`white)

q)?[tbl; enlist(or; `red; `white); 0b;()] 
red blue green yellow white purple 
---------------------------------- 
1 0 1  1  0  0 
1 0 1  1  1  0 
0 1 0  0  1  1 
1 0 1  1  0  0 

然后,您可以参数化的列名:

q)selEither:{[t; c1; c2] ?[t; enlist(or; c1 ;c2); 0b;()]} 
q)selEither[tbl; `red; `white] 
red blue green yellow white purple 
---------------------------------- 
1 0 1  1  0  0 
1 0 1  1  1  0 
0 1 0  0  1  1 
1 0 1  1  0  0 

最后,您可以从一对延长这一列名的列表

q)selAny:{[tbl; cn] ?[tbl; enlist(or/;enlist,cn); 0b;()]} 
q)selAny[t; `white`green`yellow] 
… 

查看更多在KX技术白皮书Parse Trees and Functional Forms