Join 如何在KDB中进行完全外部联接?

Join 如何在KDB中进行完全外部联接?,join,outer-join,kdb,Join,Outer Join,Kdb,我在KDB中有两个表x、y: 我想在x.a=y.a上执行与x完全外部连接y相当的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中有两个表x、y:

我想在x.a=y.a上执行与x完全外部连接y相当的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
从一开始,我能找到的最接近的东西是,但没有给出我想要的:

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

那么我如何在KDB中进行完整的外部联接呢?

这给出了您要求的结果

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
祝你一切顺利, 峡谷


编辑:为SQL语句添加排序,如:

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

您可以在KDB中使用equijoin动词

例:如果我们将其应用于示例表

        q> ej[`a;x;y]
输出:

a、b、c

137

14 7

2 5 8

2 5 9

要获得完整的外部联接,只需从表x和y中提取出非公共键,并将它们附加到equijoin结果

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

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

后退一步,想想您想要什么和您拥有什么

您需要一个外部联接,它是左联接idem的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的输出中折叠为一行。这一点需要记住,尽管给出的示例似乎与您无关。

x,如果x和y的长度不同,y将失败。我想你是想说这个很好,但是@JPC有一点道理。然而,将“by cross”替换为“by cross”并不总是这样,它会返回更多的条目。有没有办法解决这个问题?这不应该是公认的答案。它完全符合OP提供的示例,而没有执行适当的外部联接。
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