我有2个表x
,y
在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
?
对于这样一个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]
这使您所需的输出。
这给了你要求的结果
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
所有最优秀的,格伦
编辑:新增排序
退一步想想,你想要什么,你有什么。
你想一个外部联接是(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
的输出晕倒之一。这是值得记住,尽管似乎需要你的关心给你的例子不。