Power Query父子层级表转换需求:生成含所有子项的行
解决Power Query中递归获取节点及所有子项的问题
嘿,这个需求我之前也碰到过,用Power Query的递归自定义函数就能完美搞定,完全不用纠结传统意义上的循环~我给你一步步拆解实现步骤:
步骤1:整理原始数据
先把你的原始数据导入Power Query,假设导入后的表格结构是这样的:
| Name | ID | Parent |
|---|---|---|
| A | 1 | |
| B | 2 | 1 |
| C | 3 | 1 |
| D | 4 | 2 |
| E | 5 | 2 |
先把Parent列的空值替换成null(方便后续判断顶级节点):用「主页」选项卡的「替换值」功能,把空内容替换成null即可。
步骤2:创建递归自定义函数
我们需要一个递归函数来获取某个ID对应的所有子节点(包括自身)。操作如下:
- 在「查询」面板右键点击,新建一个空白查询,命名为
fnGetAllChildren - 打开该查询的「高级编辑器」,替换成以下代码:
(id as any) as table => let // 获取当前ID对应的行 CurrentRow = Table.SelectRows(Source, each [ID] = id), // 获取当前ID的直接子节点 Children = Table.SelectRows(Source, each [Parent] = id), // 递归获取每个子节点的所有子项,没有子节点就返回空表 RecursiveChildren = if Table.RowCount(Children) > 0 then List.Combine(List.Transform(Children[ID], fnGetAllChildren)) else #table({}, {}), // 合并当前行和所有递归子项 Result = Table.Combine({CurrentRow, RecursiveChildren}) in Result
注意:代码里的
Source是你原始数据查询的名称,如果你的原始查询叫别的名字,记得替换成对应的名称。
步骤3:应用函数生成结果
回到你的原始数据查询,添加一个自定义列:
- 点击「添加列」→「自定义列」,列名设为
AllDescendants - 在公式框里输入:
fnGetAllChildren([ID]),点击确定
此时表格会多出一列,每一行是一个嵌套表格,包含当前节点及所有子项。接下来展开这个嵌套表格:
- 点击自定义列右侧的展开按钮(🔽)
- 只勾选
Name和ID列,取消「使用原始列名作为前缀」的勾选 - 点击确定
步骤4:整理最终结果
展开后你就能得到想要的11行数据,最后可以删除原来的Parent列和自定义列,最终结果如下:
| Name | ID |
|---|---|
| A | 1 |
| A | 2 |
| A | 4 |
| A | 5 |
| A | 3 |
| B | 2 |
| B | 4 |
| B | 5 |
| C | 3 |
| D | 4 |
| E | 5 |
补充小提示
- 这个递归函数能自动处理更深的层级(比如再加个F是D的子节点),完全不用改代码
- Power Query默认的递归深度足够应对大多数业务场景的层级结构,不用担心报错
内容的提问来源于stack exchange,提问作者Veli Hemming
相关产品推荐
相关产品推荐

