如何在kdb+ Q中识别并关联ID匹配的数据行
在kdb+ Q中实现ID关联行的合并与统一标记
需求说明
现有一张包含FirstID、SecondID、SomeMoreData三列的表,示例数据如下:
| FirstID | SecondID | SomeMoreData |
|---|---|---|
| 123ABC | 456DEF | ... |
| 456DEF | 789GHI | ... |
| 349UYH | 286IWD | ... |
需要识别FirstID与SecondID匹配的关联行(例如第一行的SecondID「456DEF」与第二行的FirstID一致),新增Source ID列,将所有关联行统一标记为最原始的未关联FirstID,最终输出表结构如下:
| Source ID | FirstID | SecondID | SomeMoreData |
|---|---|---|---|
| 123ABC | 123ABC | 456DEF | ... |
| 123ABC | 456DEF | 789GHI | ... |
| 349UYH | 349UYH | 286IWD | ... |
逻辑伪代码(中文翻译)
如果 当前行的SecondID存在于FirstID列中: x = 找到SecondID等于当前行FirstID的那一行的FirstID 将该行的SourceID设为x 否则: 将该行的SourceID设为当前行的FirstID
Q语言实现方案
假设目标表名为t,可以通过构建ID关联映射+查找根节点的方式实现需求,具体代码如下:
// 1. 收集表中所有出现的唯一ID allIds: distinct t[`FirstID,`SecondID] // 2. 初始化父节点字典:每个ID初始默认自身为根节点 parent: allIds!allIds // 3. 遍历表,建立关联映射:将SecondID的父节点指向对应的FirstID {[p;row] p[row.SecondID]: row.FirstID; p}/[parent; t] // 4. 定义递归函数,查找ID的最顶层根节点 root: {[p;id] $[p[id]=id; id; root[p;p[id]]]} // 5. 为每行添加SourceID列,值为当前行FirstID的根节点 update SourceID: root[parent;FirstID] from t
代码说明
- 步骤1-2:先收集所有ID并初始化映射,确保每个ID都有初始的根节点
- 步骤3:通过迭代器遍历每行,建立
SecondID到对应FirstID的关联,形成ID链 - 步骤4:递归函数
root会沿着关联链找到最顶层的原始ID(根节点),即使存在多层关联(如A→B→C)也能正确识别 - 步骤5:最终为表新增
SourceID列,完成标记
内容的提问来源于stack exchange,提问作者mmv456
相关产品推荐
相关产品推荐

