kdb/q:如何基于行链起始行新增ParentRace与IsTimed列?
在kdb/q中为赛事行链分组新增ParentRace和IsTimed字段
问题背景与需求
现有一张记录跑步赛事信息的kdb/q表,同一赛事对应多行数据:
- 行链关系通过
FirstID与SecondID识别:行1的SecondID等于行2的FirstID时,行2是行1的延续 SourceID用于关联同一行链的所有行
输入表结构及示例数据:
| FirstID | SecondID | SourceID | Race | Style |
|---|---|---|---|---|
| 123ABC | 456DEF | 123ABC | Atlantic | Timed |
| 456DEF | 789GHI | 123ABC | SubAtlantic | |
| 349UYH | 286IWD | 349UYH | Pacific | Untimed |
| 286IWD | 585YYY | 349UYH | SubPacific |
输入表的kdb/q定义代码:
input:([] FirstID:`123ABC`456DEF`349UYH`286IWD; SecondID:`456DEF`789GHI`286IWD`585YYY; SourceID: `123ABC`123ABC`349UYH`349UYH; Race: `Atlantic`SubAtlantic`Pacific`SubPacific; Style: `Timed``Untimed`)
需要新增两个字段:
- ParentRace:取同一
SourceID分组的行链起始行的Race值,填充至该组所有行 - IsTimed:若同一
SourceID分组的行链起始行Style为Timed则填Yes,否则填No,应用至该组所有行
期望输出表:
| FirstID | SecondID | SourceID | Race | Style | ParentRace | IsTimed |
|---|---|---|---|---|---|---|
| 123ABC | 456DEF | 123ABC | Atlantic | Timed | Atlantic | Yes |
| 456DEF | 789GHI | 123ABC | SubAtlantic | Atlantic | Yes | |
| 349UYH | 286IWD | 349UYH | Pacific | Untimed | Pacific | No |
| 286IWD | 585YYY | 349UYH | SubPacific | Pacific | No |
实现方案
核心思路是利用SourceID分组提取起始行信息,再通过字典映射将信息广播到组内所有行,具体代码如下:
// 1. 筛选每个SourceID对应的起始行,同时计算IsTimed字段 startRows: select ParentRace:Race, IsTimed:?[Style=`Timed; "Yes"; "No"] from input where FirstID=SourceID // 2. 构建SourceID到起始行信息的映射字典 startDict: flip startRows!startRows.SourceID // 3. 为原表新增字段,通过SourceID匹配字典中的值 output: input, (startDict[`ParentRace] input.SourceID; startDict[`IsTimed] input.SourceID) as `ParentRace`IsTimed
代码解释
- 提取起始行:通过
where FirstID=SourceID筛选出每个行链的起始行,同时用三元运算符?[]生成IsTimed的结果; - 构建映射字典:将起始行的
ParentRace和IsTimed字段以SourceID为键生成字典,实现快速查找; - 填充字段:利用字典的索引能力,将每行的
SourceID对应到起始行的信息,完成组内所有行的字段填充。
执行后output表即为期望结果。
内容的提问来源于stack exchange,提问作者mmv456
相关产品推荐
相关产品推荐

