如何做一个FULL OUTER在KDB加入?

问题描述 投票:1回答:3

我有2个表xy在KDB:

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

join outer-join kdb
3个回答
0
投票

对于这样一个SQL语句:

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

您可以使用KDB(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的非公共密钥和追加他们等值连接的结果。

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

这使您所需的输出。


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

所有最优秀的,格伦

编辑:新增排序


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

警告: 联盟假定它被赋予了两套,并且将返回一组。这意味着,如果两行是在两个输入中的一个是相同的,它们将被在oj的输出晕倒之一。这是值得记住,尽管似乎需要你的关心给你的例子不。

© www.soinside.com 2019 - 2024. All rights reserved.