我在KDB中有2个表x
,y
:
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
?
答案 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
的输出中折叠为一。记住这一点,尽管您的示例似乎并不关心您。