2017-10-19 78 views
2

我正在尋找一種方法來編寫KDB中的功能選擇,以便只有在列存在的情況下才能應用where語句(爲了避免錯誤)。如果該列不存在,則默認爲true。KDB適用於只有列存在時的短語

我試過,但沒有奏效

enlist(|;enlist(in;`colname;key flip table);enlist(in;`colname;filteredValues[`colname])); 

我試着寫一個簡單的布爾表達式,並使用解析,讓我的函數形式

(table[`colname] in values)|(not `colname in key flip table) 

但KDB沒有短所以儘管右手錶達評估爲真,仍然評估左手錶情。這導致了一個奇怪的輸出boolean$()這是一個布爾值列表所有評估爲false 0b

任何幫助表示讚賞。謝謝!

EDIT 1:我不得不加入一系列條件與在詞典filters

cond,:(,/) {[l;k] enlist(in;k;enlist l[k])}[filters]'[a:(key filters)] 

然後我傳給此cond指定的參數和它被上不同表幾個不同的選擇來執行。我怎樣才能確保我放入enlist(in;k;enlist l[k]的條件表達式只會在select語句執行時被評估。

回答

1

您可以使用if-else條件$這裏做你想做的

例如:

q)$[`bid in cols`quotes;enlist (>;`bid;35);()] 
> `bid 35 
q)$[`bad in cols`quotes;enlist (>;`bad;35);()] 

注意的是,在第二個例子中,返回的是一個空列表,因爲此列是不是在報價表

所以,你可以放進這個功能選擇像這樣:

?[`quotes;$[`bid in cols`quotes;enlist (>;`bid;35);()];0b;()] 

和where子句將要應用的柱是本,否則沒有where子句將被應用:

q)count ?[`quotes;$[`bid in cols`quotes;enlist (>;`bid;35);()];0b;()] 
541 //where clause applied, table filtered 
q)count ?[`quotes;$[`bad in cols`quotes;enlist (>;`bad;35);()];0b;()] 
1000 //where clause not applied, full table returned 

希望這有助於

喬納森

AquaQ分析


編輯:如果我正確理解你更新的問題,你可能可以做類似下面的事情。首先,讓我們來定義一個「過濾器」字典的例子:

q)filters:`a`b`c!(1 2 3;"abc";`d`e`f) 
q)filters 
a| 1 2 3 
b| a b c 
c| d e f 

所以我們在這裏假設幾個不同類型的列,用於說明目的。你可以建立你的where子句的列表,像這樣:

q)(in),'flip (key filters;value filters) 
in `a 1 2 3 
in `b "abc" 
in `c `d`e`f 

(這相當於你不得不產生COND的代碼,但它是一個小整潔&更有效的 - 你也有值應徵入伍,其中ISN必要的)

然後,您可以使用vector conditional來生成應用於給定表的where子句列表,例如如你所見,在這個例子中,表「t」有列a和b,但不是c。所以使用vector有條件的,你得到a和b的where子句,但不是c。

終於到了實際應用輸出的這個名單where子句表中,你可以使用一個over來依次對每個申請:

q)l:?[key[filters] in cols[t];(in),'flip (key filters;value filters);count[filters]#()] 
q){?[x;$[y~();y;enlist y];0b;()]}/[t;l] 
a b 
--- 
1 a 
3 c 

這裏有一點要注意的是,在where子句中功能選擇,我們需要檢查,如果y是一個空列表 - 這是,所以我們可以藉助它,如果它不是一個空列表

希望這有助於

+0

非常感謝,您的代碼不會爲我工作。然而,我的問題還有另一部分。請看看我的編輯和建議。再次感謝 – KeenSeeker99

+1

對延遲道歉,但增加了一個擴展的答案,希望能夠處理你的問題的第二部分,希望它有幫助! –