2017-10-19 75 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

对延迟道歉,但增加了一个扩展的答案,希望能够处理你的问题的第二部分,希望它有帮助! –