如何在Excel中考虑‘链式关联(daisy-chaining)’进行行分组?
需求描述
现有Excel工作表数据如下:
| ID | Group |
|---|---|
| A | 1 |
| B | 1 |
| B | 2 |
| C | 2 |
| D | 3 |
规则说明:每个组内的所有ID彼此关联;若ID同时属于多个组,这些组会形成链式关联(比如B同时在组1和组2,那么A、B、C都属于同一个超级组)。需要生成包含超级组的结果表,理想输出如下:
| ID | Super-Group |
|---|---|
| A | 1,2 |
| B | 1,2 |
| C | 1,2 |
| D | 3 |
尝试用Power Query解决但未成功,希望通过连接操作实现该需求。
Power Query 实现方案
这个问题本质是找连通分量(链式关联的组集合),可以通过多次自连接+迭代合并的方式找出所有关联组,具体步骤如下:
1. 初始数据加载
- 把Excel数据导入Power Query(点击「数据」选项卡→「从表格/区域」),将查询重命名为
原始数据。
2. 预处理映射表
- 新建查询引用
原始数据,移除ID列后去重,得到唯一组列表,命名为组列表; - 再新建查询引用
原始数据,按ID分组,将每个ID对应的Group列用逗号合并,得到ID-组映射表(方便后续关联)。
3. 迭代找出所有关联组(核心步骤)
- 新建查询引用
组列表,添加自定义列关联组,初始值等于当前Group值; - 进入循环迭代(直到关联组不再新增):
- 将当前表与
原始数据左连接,连接条件为当前表[Group] = 原始数据[Group],展开原始数据的ID列; - 再将表与
原始数据左连接,连接条件为展开后的ID = 原始数据[ID],展开原始数据的Group列,重命名为关联组候选; - 按Group列分组,把
关联组和关联组候选合并成列表,去重后用逗号连接,更新关联组列; - 对比本次迭代和上一次的
关联组列,如果完全一致就停止循环,否则重复上述操作。
- 将当前表与
4. 关联回原始ID并整理输出
- 将迭代后的组-超级组映射表与
原始数据左连接,连接条件为原始数据[Group] = 组映射[Group]; - 展开
关联组列,重命名为Super-Group; - 移除冗余的Group列,对ID和Super-Group去重(同一个ID可能对应多个组,但超级组唯一);
- 调整列顺序为ID、Super-Group,加载回Excel。
简化版M代码(直接可用)
如果不想手动操作,替换数据源名称后直接用以下代码:
let 源 = Excel.CurrentWorkbook(){[Name="Table1"]}[Content], 更改类型 = Table.TransformColumnTypes(源,{{"ID", type text}, {"Group", type text}}), 组列表 = Table.Distinct(Table.SelectColumns(更改类型,{"Group"})), 初始关联 = Table.AddColumn(组列表, "关联组", each [Group]), // 定义迭代函数 迭代关联 = (inputTable as table) as table => let 连接ID = Table.NestedJoin(inputTable, {"Group"}, 更改类型, {"Group"}, "原始数据", JoinKind.LeftOuter), 展开ID = Table.ExpandTableColumn(连接ID, "原始数据", {"ID"}, {"ID"}), 连接关联组 = Table.NestedJoin(展开ID, {"ID"}, 更改类型, {"ID"}, "关联组数据", JoinKind.LeftOuter), 展开关联组 = Table.ExpandTableColumn(连接关联组, "关联组数据", {"Group"}, {"关联组候选"}), 分组合并 = Table.Group(展开关联组, {"Group"}, {{"关联组", each Text.Combine(List.Distinct(List.Combine({[关联组], [关联组候选]})), ","), type text}}), 是否变化 = Table.Equal(inputTable, 分组合并) in if 是否变化 then inputTable else @迭代关联(分组合并), 最终组关联 = 迭代关联(初始关联), 连接原始数据 = Table.NestedJoin(更改类型, {"Group"}, 最终组关联, {"Group"}, "超级组数据", JoinKind.LeftOuter), 展开超级组 = Table.ExpandTableColumn(连接原始数据, "超级组数据", {"关联组"}, {"Super-Group"}), 去重 = Table.Distinct(展开超级组), 整理列 = Table.ReorderColumns(去重,{"ID", "Super-Group"}) in 整理列
内容的提问来源于stack exchange,提问作者Harmon Tamura
相关产品推荐
相关产品推荐

