Join 如何在KDB中进行完全外部联接?
我在KDB中有两个表x、y: 我想在x.a=y.a上执行与x完全外部连接y相当的SQL操作,也就是说,我想得到以下结果: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 从一开始,我能找到的最接近的东西是
([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