如何在kdb中执行高效的左连接?

时间:2016-09-21 21:22:35

标签: 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

任何人都可以为我提供一些更快和/或更好的 另一种方式?我真的很想避免使用不同的,例如。

2 个答案:

答案 0 :(得分: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解决方案

很好的解决方案Connor。我修改了你的缩短/简化代码:

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

答案 1 :(得分:1)

以@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