首页 文章

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

提问于
浏览
2

我正在寻找一种在KDB中编写函数select的方法,这样只有在列存在时才会应用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没有短路,所以尽管右 Watch 达式评估为true,仍然会评估左 Watch 达式 . 这导致了一个奇怪的输出 boolean$() ,这是一个布尔值列表,所有评估为false 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 回答

  • 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
    

    所以这里我们假设一些不同类型的不同列,用于说明目的 . 你可以 Build 你的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是否为空列表 - 如果它不是空列表,我们就可以将其列入

    希望这可以帮助

相关问题