如何在 kdb 中执行高效的左连接?
How do I perform an efficient left join in kdb?
我想要 运行 KDB+ / Q 中的常规 SQL 式左连接。
- 对于左边的每一行,我们在结果中至少得到一行
table.
- 如果右边有多个匹配项table,我得到一行
每一个,不仅仅是第一场比赛
测试数据
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
我想要 运行 KDB+ / Q 中的常规 SQL 式左连接。
- 对于左边的每一行,我们在结果中至少得到一行 table.
- 如果右边有多个匹配项table,我得到一行 每一个,不仅仅是第一场比赛
测试数据
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