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

How do I perform an efficient left join in kdb?

我想要 运行 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

谁能给我提供一个在某些方面更快 and/or 更好的 另一种方式?例如,我真的很想避免使用 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 连接的免费教程,在此处演示了所有连接:http://www.timestored.com/kdb-guides/qsql-inner-left-joins

因为我们想要每一行..基于@Connors 解决方案

康纳,不错的解决方案。我将你的代码修改为 shorten/simplify 代码:

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