【问题标题】:How to pass dictionary into query constraint?如何将字典传递给查询约束?
【发布时间】:2016-05-15 20:08:15
【问题描述】:

如果这是约束字典:

dictName:`region`Code;
dictValue:(`NJ`NY;`EEE213);
dict:dictName!dictValue;

我想将 dict 传递给一个函数,并取决于有多少键,并让查询做出相应的反应。如果有一个关键区域,那么我想把它写成

select from table where region in dict`region;

代码也是如此。但是如果我传递两个键,我希望查询知道并将其传递为:

select form table where region in dict`region,Code in dict`code;

有什么办法吗?

我想出了这个代码:

 funcForOne:{[constraint]?[`bce;enlist(in;constraint;(`dict;enlist constraint));0b;()]};

funcForAll[]
{[dict]$[(null dict)~1;select from bce;($[(count key dict)=1;($[`region in (key dict);funcForOne[`region];funcForOne[`Code]]);select from bce where region  in dict`region,rxmCode in dict`Code])]};

它适用于一个和两个约束。但是当我打电话给funcForAll[] 时,它给出了类型错误。我应该如何改变它?我认为它来自 null dict~1 我也试过数。但效果不太好。

更新

所以我这样做了,但我有一些错误

    tab:([]code:`B90056`B90057`B90058`B90059;region:`CA`NY`NJ`CA);                                                                                             
dictKey:`region`Code;dictValue:(`NJ`NY;`B90057);
dict:dictKey!dictValue;
?[tab;f dict;0b;()]; 

我得到了 'NY 错误。你知道为什么吗?另外,如果我传递一个空字典,它似乎不起作用。

【问题讨论】:

  • 检查选择的功能形式。每当有动态查询创建案例时,功能形式就是这样做的方法。
  • 谢谢拉胡尔。我正在考虑这样做。但是我怎样才能只用一个键或两个键将字典传递给它呢?谢谢
  • 我尝试编写一个函数,它可能适用于一两个约束。但是当它没有通过任何东西时,就会出现类型错误。我如何编写一个不传递任何内容、一个约束、两个约束的函数?

标签: kdb


【解决方案1】:

正如我所说,功能形式会是更好的方法,但如果您的要求非常有限,那么您可以考虑以下其他解决方案:

注意:假设所有字典键都在表列列表中。

q) f:{[dict] if[0=count dict;:select from t]; 
   select from t where (#[key dict;t]) in {$[any 0<=type each value x;flip ;enlist ]x}[dict] }

解释: 1. 根据值类型将 dict 转换为 table。如果任何值是一个通用列表,则翻转,否则进行登记。

            $[any 0<=type each value dict;flip ;enlist ]dict
  1. 获取表 t 的子集,其中仅包含作为列的字典键。

           #[key dict;t]
    
  2. 获取 (2) 在 (1) 中的行

基本上我们使用以下形式的查询和匹配:

   q)t1:([]id:1 2;s:`a`b);
   q)t2:([]id:1 3 ;s:`a`b);
   q)select from t1 where ([]id;s) in t2

【讨论】:

    【解决方案2】:

    如果你只是使用in,你可以这样做:

    f:{{[x;y](in),'key[y],'(),x}[;x]enlist each value[x]}
    

    这样:

    q)d
    a| 10 1
    b| ,`a
    q)f d
    in `a 10 1
    in `b ,`a
    
    q)t
    a b c
    ------
    1 a 10
    2 b 20
    3 c 30
    q)?[t;f d;0b;()]
    a b c
    ------
    1 a 10
    

    请注意,由于enlist each,结果列表被征用,因此单例也可以工作:

    q)d:enlist[`a]!enlist 1
    q)d
    a| 1
    q)?[t;f d;0b;()]
    a b c
    ------
    1 a 10
    

    更新到次要问题

    这仍然适用于空字典,即()!()。我正在传入字典变量。

    在您的第二个问题中,您的字典构造不正确(还要记住 q 区分大小写)。此外,您的价值观也需要入伍。在 kx 网站的参考页面中查找功能选择,您会看到您需要加入符号列表以将它们与列名声明区分开来

    `region`code!(enlist `NY`NJ;enlist `B90057)
    

    【讨论】:

    • 谢谢,如果jave传递空键和空值怎么办?只有字典名吗?
    • 所以我这样做了,但我有一些错误选项卡:([]code:B90056B90057B90058B90059;region:CANYNJCA);dictKey:region代码;dictValue:(NJNY;`B90057);dict:dictKey!dictValue;?[tab;f dict;0b;()];我得到了 'NY 错误。你知道为什么吗?谢谢,特里
    • @Terry 这仍然适用于空字典,即()!()。我正在传入字典变量。您的第二条消息您的字典构造不正确(还要记住 q 区分大小写)。此外,您的价值观也需要入伍。在参考中查找功能选择,您会发现您需要加入符号列表以将它们与列名声明区分开来:`region`code!(enlist `NY`NJ;enlist `B90057)
    猜你喜欢
    • 2018-01-06
    • 2016-02-23
    • 2013-02-15
    • 2014-10-12
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多