在 Power Query 中处理数据时,经常会遇到这样的情况:两个查询中都有“单位名称”列,但每个单元格内的单位顺序可能不同(例如 “甲公司、乙公司” 与 “乙公司、甲公司”)。直接比较文本会认为它们不同,但实际上内容一致。本文将介绍如何通过拆分、排序再比较的方法,准确判断两个文本列表是否相同,并分享处理空值(null)的实用技巧。
问题背景
假设有两个查询:
查询 A 的单位名称:
丙公司、甲公司、乙公司查询 B 的单位名称:
甲公司、乙公司、丙公司
肉眼可见它们包含相同的三个单位,但直接使用等于(=)判断会返回 false。我们需要一种方法,忽略顺序的影响,只比较内容是否一致。
解决思路
核心思想:将文本拆分成单位列表 → 对列表排序 → 比较排序后的列表(或合并后再比较)。排序后,无论原始顺序如何,都会得到相同顺序的列表,从而可以进行公平比较。
具体步骤
第一步:将文本拆分成列表
使用 Text.Split 函数,根据实际分隔符(如顿号、逗号)将单位名称拆分为列表。
假设待拆分的列名是“单位名称”,分隔符是顿号“、”,添加自定义列:
| |
如果分隔符不固定,可能需要先用替换函数统一分隔符,或使用 Splitter.SplitTextByAnyDelimiter 等高级方法,但本文以顿号为例。
第二步:对列表进行排序
使用 List.Sort 对第一步得到的列表进行排序。可以直接在同一个自定义列公式中嵌套:
| |
这样,原始文本被拆分后立即排序,生成一个顺序统一的列表。
第三步:执行内容比较
现在有两个查询都生成了排序后的列表列(假设命名为“排序后列表1”和“排序后列表2”)。可以采用以下两种方式判断它们是否相同:
方法 A:使用 List.Difference
List.Difference 返回第一个列表中有但第二个列表中没有的项目。如果返回空列表 {},说明两个列表内容一致。
添加自定义列进行判断:
| |
结果返回 true 或 false。
方法 B:合并为文本后再比较
如果后续需要保留文本格式,也可以将排序后的列表用 Text.Combine 合并回字符串,然后直接比较。
| |
处理空值(null)避免报错
在实际数据中,难免会有单元格为空(null)。如果不加处理,Text.Split 会报错:“无法将值 null 转换为类型 Text”。解决方法是添加空值判断或错误处理。
推荐:在拆分排序时返回空列表
修改自定义列公式,如果原始值为 null,则返回空列表 {}:
| |
这样做的好处是:
后续操作(如提取值、
Text.Combine)不会因为 null 而中断。空列表在合并时会得到空字符串
"",符合逻辑预期。
备选:在后续拼接时处理 null
如果你希望保留 null 以区分“无数据”和“空数据”,可以在最后合并列表时做判断:
| |
或使用 try…otherwise:
| |
但请注意,如果使用界面上的“提取值”功能(右键点击列表列 → 提取值),该功能无法处理包含 null 的列表列,会直接报错。因此,如果打算使用提取值,强烈建议在生成列表列时就避免 null(即返回空列表)。
完整示例
假设数据如下:
| 单位名称(原始) |
|---|
| 丙公司、甲公司、乙公司 |
| 乙厂、甲厂、丙厂 |
| null |
- 添加排序列表列
公式:= if [单位名称] <> null then List.Sort(Text.Split([单位名称], "、")) else {}
结果列将包含:
{"甲公司","乙公司","丙公司"}{"甲厂","乙厂","丙厂"}{}(空列表)
- 合并回文本(可选)
公式:= Text.Combine([排序后列表], "、")
结果:
甲公司、乙公司、丙公司甲厂、乙厂、丙厂""(空字符串)
- 与另一个查询比较
假设有另一个查询的对应列表列名为“排序后列表B”,判断是否相等:= List.Difference([排序后列表], [排序后列表B]) = {}
总结
核心函数:
Text.Split、List.Sort、List.Difference、Text.Combine。关键技巧:先拆分再排序,消除顺序影响。
空值处理:在拆分排序时就返回空列表
{},可以简化后续操作,避免报错。适用场景:对比单位名称、关键词列表、标签集合等任何顺序不重要但内容需一致的文本数据。
通过以上方法,你可以轻松在 Power Query 中实现忽略顺序的文本内容比较,并稳健地处理空值。希望这篇笔记对你的数据处理工作有所帮助!