2017-09-07 122 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