2016-09-21 131 views
5

我想运行一个常规的SQL风格左加入KDB +/Q.如何在kdb中执行高效的左连接?

  • 我们得到的结果至少一行在离开 表的每一行。
  • 如果右表中的一个以上的比赛,我得到一排 每个那些,不只是第一场比赛

测试数据

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 

谁能为我提供一个在某些 其他方式更快和/或更好?例如,我真的很想避免使用不同的字体。

回答

0

建立在@ 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 
+0

哇,谢谢! Connor,我还没有读k。 **你能解释一下你做了什么吗?** 再次感谢! – JSLover

+0

这是q实现。 'q)nungroup:{$ [count x:0!x;,/ [翻转每个x],首先每个,/ [x]; x]}' –

+0

@Connor Gervin:您的解决方案给出错误的结果。 'x:([] a:1 1 2 3 4; b:3 4 5 6 100)' –

1
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免费加入教程演示所有的人都在这里:http://www.timestored.com/kdb-guides/qsql-inner-left-joins

因为我们希望在@Connors解决方案

很好的解决方案康纳每row..based。我修改了您的代码以缩短/简化代码:

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更快,对这种特殊情况使用更少的内存。

+0

它是否符合第一个要求(我们在结果中左边表格中的每一行至少得到一行)?我想OP希望把'3 6 0N'包括进去。 –

+2

感谢您的帮助! 对,我们在结果中至少需要一行左表中的每一行。 即使在使用kdb“lj”操作时,ungroup/xgroup技巧总是会导致内部连接。这是因为组合表中左连接产生的空行包含来自不匹配表的列的零长度列表。当这些被取消分组时,它们产生零行而不是包含空条目的单行。 当列表值列的长度为零时,生成一个具有空值的单行的ungroup版本是否合理? TX! – JSLover

+0

所以,现在我发现我自己在做一些我认为可能是非常糟糕的形式。我避免使用字符串。我这样做是因为字符串,因为我正在使用它们,打破了这里提出的方法。例如,再次运行该解决方案,并使用字符串列的新值x解决方案失败。 x:([]; a:1 1 2 3; b:3 4 5 6; z:(“foo”;“bar”;“baz”;“bang”)) – JSLover