【问题标题】:How to do a between join clause in KDB?如何在 KDB 中做一个 between join 子句?
【发布时间】:2019-09-08 21:14:04
【问题描述】:

假设我有一个表 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 中进行逻辑上看起来像的联接

select A.bucket_start_date, A.bucket_end_date, sum(coins) from A join B where B.date BETWEEN A.bucket_start_date and A.bucket_end_date group by 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

【问题讨论】:

    标签: kdb


    【解决方案1】:

    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看看有什么区别。

    【讨论】:

    • 有没有办法也有一个函数是 sum((B.date - A.bucket_start_date) * B.coins) 而不是 sum(B.coins) 的列?我想要的是一列由开始日期的距离加权的硬币加权总和,而不是简单的列总和
    【解决方案2】:

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

    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
    

    从 () 括号内开始。

    q)get each data
    2015.05.02 2015.05.08
    2015.05.08 2015.05.12
    

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

    bucketSt   bucketEnd  coins
    ---------------------------
    2015.05.02 2015.05.08 16
    2015.05.08 2015.05.12 32
    

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

    【讨论】:

    • 下划线_ 不是符号和列名中的问题字符,所以总的来说我认为使用_ 的做法很好。所有其他字符是的。
    • 有没有办法也有一个函数是 sum((B.date - A.bucket_start_date) * B.coins) 而不是 sum(B.coins) 的列?我想要的是一列由开始日期的距离加权的硬币加权总和,而不是简单的列总和
    猜你喜欢
    • 2020-07-02
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多