具有多个值kdb \ q的调用函数

时间:2018-06-29 18:06:19

标签: kdb

我有一个函数声明:

func:{[id;time] select last synp from synp_t where instr_id = id, tp_time < time}

其中instr_id的类型为i,而tp_time的类型为v

例如,func[8;05:00:11]工作正常,并给了我17.55的价值。

但是,如果我尝试func[8 1;05:00:11 07:10:59],则会得到:

'length ERROR: incompatible lengths (different lengths of operands for synchronized operation or table columns lengths are not the same

例如,我想得到的是17.55 9.66

如果我执行select res:func_demo[id;time]from tab,其中也会出现同样的错误,其中tab是具有instr_idtp_time两列的表。

我猜enlist可能可以解决问题,但我不知道该如何使用。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:5)

这里的两个答案都很好,但是没有详细说明为什么会出现'length错误。错误完全归因于您的where子句where instr_id = id, tp_time < time。传递项目列表时,实际上创建了一个布尔列表的列表,这些布尔列表将传递给where子句。设置两个示例列表以突出显示此内容:

q)show instr_id:-5?10
2 8 0 1 6
q)show tp_time:5?.z.t
01:05:42.696 03:42:39.320 17:44:49.101 15:01:01.470 05:47:49.777

使用原子和列表运行第一个条件instr_id = id

q)instr_id=2
10000b
q)instr_id=2 8
'length
  [0]  instr_id=2 8
               ^

使用=仅对长度等于instr_id的原子起作用。如果您想传递多个项目以进行匹配,则可以使用in

q)instr_id in 2
10000b
q)instr_id in 2 8
11000b

对于第二个条件tp_time < time再次要求传递相同长度的原子或列表:

q)tp_time<.z.t
11111b
q)tp_time<.z.t,.z.t
'length
  [0]  tp_time<.z.t,.z.t
              ^

可以通过使用副词来解决此问题,例如将每条权利/:比较tp_time与多个项目,并使用any将其缩减为一个列表:< / p>

q)tp_time</:.z.t,.z.t
11111b
11111b
q)any tp_time</:.z.t,.z.t
11111b

希望这可以帮助您了解上面遇到的问题。

答案 1 :(得分:4)

func'[8 1;05:00:11 07:10:59]应该可以工作

它使用两个词副词,这将在两个输入列表的相应元素之间应用功能

有关副词的更多信息,请参见http://code.kx.com/q/ref/adverbs/。它们非常强大。

许多内置函数都能够将原子和列表作为输入并相应地工作,但是使用用户定义的函数,您很可能需要使用副词来在各种情况下使用它们

答案 2 :(得分:3)

我建议使用aj来获得结果,在查询中看起来像您想要给定id的最后价格并且小于输入time的价格。 / p>

q)func:{[id;time] aj[`instr_id`tp_time; ([] instr_id:id;tp_time: time);synp_t]}
q)func[1 1 2;05:00:11 07:10:59 10:10:00]

使用each-both,您将n次调用该函数并选择n次数据。 aj是强大的功能之一 Kdb以asof的价格提供。

实际上,您不需要func函数,您可以使用aj直接获得结果。

aj[`instr_id`tp_time; update instr_id:id, tp_time: time from tab;synp_t]