我有一个函数声明:
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_id
和tp_time
两列的表。
我猜enlist
可能可以解决问题,但我不知道该如何使用。我该如何解决这个问题?
答案 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]