仅当列存在时,KDB才应用短语

时间:2017-10-19 09:24:42

标签: kdb

我正在寻找一种在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语句执行时得到评估。

1 个答案:

答案 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是否为空列表 - 如果它不是空列表,我们就可以登记它

希望这有帮助