假设我有一个表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
答案 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
也有可能进行窗口连接,这更有效,但这应该很容易理解。希望对您有帮助!