如何在KDB中进行全面加入?

时间:2014-10-27 11:39:00

标签: join outer-join kdb

我在KDB中有2个表xy

x:([a:1 1 2 3]; b:3 4 5 6)
q) a | b
   -----
   1 | 3
   1 | 4
   2 | 5
   3 | 6

y:([a:1 2 2 4]; c:7 8 9 10)
q) a |  c
   ------
   1 |  7
   2 |  8
   2 |  9
   4 | 10

我想做x FULL OUTER JOIN y ON x.a = y.a的SQL等价物,也就是说,我想得到结果:

([a:1 1 2 2 3 4]; b:3 4 5 5 6 0N; c:7 7 8 9 0N 10)
q) a |   b   c
   -----------
   1 |   3   7
   1 |   4   7
   2 |   5   8
   2 |   5   9
   3 |   6 0Nj
   4 | 0Nj  10

KDB reference开始,我能找到的最接近的是uj但是没有给出我想要的东西:

x uj y
q) a |   b   c
   -----------
   1 |   3   7
   2 |   5   8
   3 |   6 0Nj
   4 | 0Nj  10

那么如何在KDB中进行FULL OUTER JOIN

3 个答案:

答案 0 :(得分:1)

这会给出您要求

的结果
q)`a xasc 1!distinct (uj). 0!/:lj'[(x;y);(y;x)]
a| b c
-| ----
1| 3 7
1| 4 7
2| 5 8
2| 5 9
3| 6
4|   10

一切顺利, 格伦

编辑:添加排序

答案 1 :(得分:0)

对于如下的SQL语句:

从x,y中选择,其中x.a = y.a

你可以在KDB中使用equijoin动词(http://code.kx.com/q/ref/joins/#ej-equi-join)。

例如:如果我们将它应用于您的示例表

        q> ej[`a;x;y]

输出:

a b c

1 3 7

1 4 7

2 5 8

2 5 9

要获得完全外连接,只需从表x和y中提取非公共密钥,然后将它们附加到equijoin结果。

             q> r,(0!x,'y) except r:ej[`a;x;y]

这为您提供了所需的输出。

答案 2 :(得分:0)

退后一步,想一想自己想要的东西和拥有的东西。

您想要一个外部联接,它是左联接(同上)和右联接(等效于左联接)的并集(在q中可用),所以我们就可以这样做:

q)oj:{
    lxy:0!lj[x;y];                  // Left join (plus remove keys)
    lyx:(cols lxy) xcols 0!lj[y;x]; // Right join (plus remove keys 
                                    // and prepare cols order for union)
    (cols key x) lxy union lyx      // Union (plus retrieve keys)
    };

q)oj[x;y]
a| b c
-| ----
1| 3 7
1| 4 7
2| 5 8
3| 6
2| 5 9
4|   10

当然,您可以将其设置为不透明的单行代码,以适合q社区:

q)(cols key x) xkey ((cols lxy) xcols 0!lj[y;x]) union lxy:0!lj[x;y]
a| b c
-| ----
1| 3 7
2| 5 8
2| 5 9
4|   10
1| 4 7
3| 6

警告:
Union假定给定了两组,并将返回一组。这意味着,如果两个输入之一中的两行相同,则它们将在oj的输出中折叠为一。记住这一点,尽管您的示例似乎并不关心您。