如何在KDB中执行between join子句?

时间:2019-09-08 21:14:04

标签: kdb

假设我有一个表A,其中的列bucket_start_date,bucket_end_date,

A
bucket_start_date | bucket_end_date
2015.05.02        | 2015.05.08
2015.05.08        | 2015.05.12

还假设我有一个表B,其中列有日期,硬币。

A
date        | coins
2015.05.02  | 5
2015.05.06  | 11     
2015.05.09  | 32

如何在逻辑上看起来像kdb的联接

从A连接B中选择A.bucket_start_date,A.bucket_end_date,总和(硬币),其中B.date在A.bucket_start_date和A.bucket_end_date之间按A.bucket_start_date,A.bucket_end_date

所以我希望结果看起来像

bucket_start_date | bucket_end_date | sum(coins) 
2015.05.02        | 2015.05.08      | 16 
2015.05.08        | 2015.05.12      | 32

2 个答案:

答案 0 :(得分:3)

window join是获得此结果的自然方法。以下是一个wj1函数,该函数将获得您想要的东西:

q)wj1[A`bucket_start_date`bucket_end_date;`date;A;(B;(sum;`coins))]
bucket_start_date bucket_end_date coins
---------------------------------------
2015.05.02        2015.05.08      16
2015.05.08        2015.05.12      32

第一个变量是一对日期列表,第一个是开始日期,最后一个是结束日期。

第二个变量是公共列,在这种情况下,您要使用date列,因为您正在查找每个日期适合的窗口。

第三个和第四个变量包含要连接的简单表,最后(sum;`coins)是要应用于给定列的函数的列表。同样,在这种情况下,您需要对每个窗口中的硬币列求和。

wj会考虑进入每个间隔时的主要值,而wj1会考虑仅出现在每个间隔中的值。您可以在函数中将wj1更改为wj来查看区别。

答案 1 :(得分:1)

首先,最好不要在命名约定中使用_,因为_也在q中用作drop运算符。

man ld

但是没有窗口连接的问题的解决方案可以是相当简单的选择语句。

q)data:([]bucketSt:2015.05.02 2015.05.08;bucketEnd:2015.05.08 2015.05.12)
q)daterange:([]date:2015.05.02 2015.05.06 2015.05.09; coins: 5 11 32)

从()括号的内部开始。

update coins:({exec sum coins from daterange where date within x} each get each data) from data

返回每一行的开始和结束时间。 带有聚合的简单exec语句从daterange表中获取必要的结果。最后,在原始表上使用带有新值的update语句。返回表如下:

q)get each data
2015.05.02 2015.05.08
2015.05.08 2015.05.12

也有可能进行窗口连接,这更有效,但这应该很容易理解。希望对您有帮助!