我正在寻找一种在KDB中编写功能选择的方法,这样只有在列存在时才会应用where短语(为了避免错误)。如果列不存在,则默认为true。
我尝试了这个,但它没有工作
enlist(|;enlist(in;`colname;key flip table);enlist(in;`colname;filteredValues[`colname]));
我尝试编写一个简单的布尔表达式并使用parse来获取我的函数形式
(table[`colname] in values)|(not `colname in key flip table)
但是kdb没有短路,所以尽管右手表达式评估为真,仍然会评估左手表达式。这导致了一个奇怪的输出boolean$()
,这是一个布尔值列表,所有布尔值都评估为假0b
感谢任何帮助。谢谢!
编辑1:我必须使用字典filters
中指定的参数加入一系列条件
cond,:(,/) {[l;k] enlist(in;k;enlist l[k])}[filters]'[a:(key filters)]
然后我传递此cond
并在不同表上的几个不同选择上执行它。我怎样才能确保代替enlist(in;k;enlist l[k]
的任何条件表达式只会在select语句执行时得到评估。
答案 0 :(得分: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 Analytics
编辑:如果我正确理解您的更新问题,您可以执行以下操作。首先,让我们定义一个示例“过滤器”字典:
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的代码,但是它有点整洁,效率更高 - 你也有登记的值,这是没有必要的)
然后,您可以使用vector conditional生成要应用于给定表的where子句列表,例如
q)t:([] a:1 2 3 4 5 6;b:"adcghf")
q)?[key[filters] in cols[t];(in),'flip (key filters;value filters);count[filters]#()]
(in;`a;,1 2 3)
(in;`b;,"abc")
()
如您所见,在此示例中,表“t”具有列a和b,但不包含c。因此,使用矢量条件,你得到a和b的where子句但不是c。
最后,为了将这个子句的输出列表实际应用到表中,您可以使用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是否为空列表 - 如果它不是空列表,我们就可以登记它
希望这有帮助