Join 如何在kdb中执行有效的左连接?
我想在KDB+/Q中运行一个传统的SQL风格的左连接Join 如何在kdb中执行有效的左连接?,join,left-join,kdb,q-lang,Join,Left Join,Kdb,Q Lang,我想在KDB+/Q中运行一个传统的SQL风格的左连接 对于左边的每一行,结果中至少有一行 桌子 如果在正确的表中有多个匹配项,我将为 每一个,不仅仅是第一场比赛 测试数据 x:([];a:1 1 2 3; b:3 4 5 6) y:([]; a:1 2 2 4; c:7 8 9 10) 我能想到的最好的版本是这样的: 这会将仅提供第一个匹配项的左联接附加到提供所有匹配项的内部联接,然后删除重复项: distinct ej[`a; x; y] , x lj `a xkey y
- 对于左边的每一行,结果中至少有一行 桌子
- 如果在正确的表中有多个匹配项,我将为 每一个,不仅仅是第一场比赛
x:([];a:1 1 2 3; b:3 4 5 6)
y:([]; a:1 2 2 4; c:7 8 9 10)
我能想到的最好的版本是这样的:
这会将仅提供第一个匹配项的左联接附加到提供所有匹配项的内部联接,然后删除重复项:
distinct ej[`a; x; y] , x lj `a xkey y
有人能给我提供一些更快和/或更好的吗
其他方式?例如,我真的希望避免使用distinct
q)`a xgroup y // group the lookup table by keys
a| c
-| ---
1| ,7
2| 8 9
4| ,10
q)x lj `a xgroup y // join all combinations
a b c
------------
1 3 ,7
1 4 ,7
2 5 8 9
3 6 `long$()
q)ungroup x lj `a xgroup y // unroll using ungroup to produce a flat table
a b c
-----
1 3 7
1 4 7
2 5 8
2 5 9
我们提供了一个关于kdb连接的免费教程,在这里演示了所有这些连接:
因为我们需要每一行..基于@Connors解决方案
很好的解决方案,康纳。我修改了您的代码以缩短/简化代码:
q)bungroup:{ungroup {$[0=count x; (),first x; x]}''[x]}
q)bungroup x lj `a xgroup y
a b c
--------
1 3 7
1 4 7
2 5 8
2 5 9
3 6
4 100 10
仅供参考:Connors在这种情况下速度更快,占用的内存更少。基于@Ryan的答案
k)nungroup:{$[#x:0!x;(,/){$[#t:+:x;t;enlist *:'[x];t]}'[x]]}
q)nungroup:{$[count x:0!x;(,/){$[count t:flip x;t;enlist first'[x]]}'[x];x]}
q)nungroup x lj ` \`a xgroup y
a b c
-----
1 3 7
1 4 7
2 5 8
2 5 9
3 6
它是否满足第一个要求(对于左表中的每一行,结果中至少有一行)?我猜OP希望
36 0N
包含在结果中。感谢您的帮助!对,对于左表中的每一行,结果中至少需要一行。解组/xgroup技巧始终导致内部联接,即使使用kdb“lj”操作也是如此。这是因为分组表上的左联接生成的空行包含来自不匹配表的列的零长度列表。当这些项被解组时,它们将生成零行,而不是包含空项的单行。当列表值列的长度为零时,有一个版本的ungroup生成一个具有null entires的单行,这有意义吗?德克萨斯州!所以,现在我发现我自己在做一些我认为可能非常糟糕的事情。我在避免使用字符串。我这样做是因为字符串在我使用它们时破坏了这里提出的方法。例如,如果解决方案失败,请使用新值x和字符串列再次运行该解决方案。x:([];a:11123;b:3456;z:(“foo”,“bar”,“baz”,“bang”))哇,谢谢!康纳,我还没读k。你能解释一下你做了什么吗?再次感谢!这是q实现<代码>q)nungroup:{$[count x:0!x;,/[flip each x],first each,/[x];x]}@Connor Gervin:您的解决方案给出了错误的结果,例如,x:([]a:1:2:3;b:3:4:5:6 100)
good spot@Igor Korkhov,这应该会起作用<代码>q)nungroup:{$[count x:0!x;(,/){$[0=count:flip x;登记第一个'[x];t]}'[x];x]}很好的解决方案,我喜欢使用first。将您的修改为更简单但稍慢的版本。