Power Query中判断子集内两行存在性的报错排查
问题:Power Query中Table.Contains使用报错解决思路
目标是查询文件夹中的文件(唯一标识为Col1+Col2),标记两类文件:
- Option 1:包含
I/R列值为I且Info列包含A1/A2的行,同时存在同标识下I/R列值为R且Info列包含B的行 - Option 2:仅包含
I/R列值为I且Info列包含A1/A2的行,无对应R+B的行
为实现判断,创建了Helper R列和Concat Info列,还做了不含后续步骤的辅助查询HELPER QUERY避免循环引用。但运行添加Outcome列的步骤时,符合第一个if条件的行都报错:[Expression.Error] We cannot convert the value false to Type Record,无论Helper R值是true/false都会触发。
错误的M代码
= Table.AddColumn(#"Changed Type1", "Outcome", each if ([#"I/R"]= "I") and (Text.Contains([Info], "A1") or Text.Contains([Info], "A2")) then if Table.Contains(#"HELPER QUERY",#"HELPER QUERY"[Concat Info] = "R "&[Col1]&" "&[Col2],#"HELPER QUERY"[Helper R]=true) then "Option 1" else "Option 2" else "Other")
相关数据表格
| Col1 | Col2 | I/R | Info | Concat Info | Helper R |
|---|---|---|---|---|---|
| 123456 | 10 | I | A1 | A1 123456 10 | FALSE |
| 123456 | 10 | I | A2 | A2 123456 10 | FALSE |
| 123456 | 10 | I | B | B 123456 10 | FALSE |
| 123456 | 20 | I | B | B 123456 20 | FALSE |
| 123456 | 20 | I | B | B 123456 20 | FALSE |
| 123456 | 20 | I | B | B 123456 20 | FALSE |
| 123456 | 25 | R | B | B 123456 25 | TRUE |
| 123456 | 30 | I | B | B 123456 30 | FALSE |
| 123456 | 30 | I | B | B 123456 30 | FALSE |
| 123456 | 30 | I | B | B 123456 30 | FALSE |
| 123456 | 30 | I | B | B 123456 30 | FALSE |
| 123456 | 30 | I | B | B 123456 30 | FALSE |
| 123456 | 30 | R | B | B 123456 30 | TRUE |
| 123456 | 30 | R | B | B 123456 30 | TRUE |
| 123456 | 40 | I | B | B 123456 40 | FALSE |
| 123456 | 40 | I | B | B 123456 40 | FALSE |
| 123456 | 40 | I | B | B 123456 40 | FALSE |
| 123456 | 40 | I | B | B 123456 40 | FALSE |
| 123456 | 40 | R | B | B 123456 40 | TRUE |
| 123456 | 40 | R | A1 | A1 123456 40 | FALSE |
| 123456 | 50 | I | A1 | A1 123456 50 | FALSE |
| 123456 | 50 | I | A2 | A2 123456 50 | FALSE |
| 345876 | 50 | I | A1 | A1 345876 50 | FALSE |
| 345876 | 50 | I | B | B 345876 50 | FALSE |
| 345876 | 50 | R | B | B 345876 50 | TRUE |
| 345876 | 50 | R | B | B 345876 50 | TRUE |
| 345876 | 50 | R | B | B 345876 50 | TRUE |
| 345876 | 60 | I | B | B 345876 60 | FALSE |
解决思路
1. 错误根源:Table.Contains参数使用错误
Table.Contains的第二个参数要求是记录类型,但你传入的是布尔表达式(#"HELPER QUERY"[Concat Info] = "R "&[Col1]&" "&[Col2]),返回的是布尔值而非符合表格结构的记录,因此触发类型转换错误。
2. 修正方案一:改用Table.SelectRows判断行存在
直接筛选辅助查询中符合条件的行,再通过行数判断是否存在:
= Table.AddColumn(#"Changed Type1", "Outcome", each if ([#"I/R"] = "I") and (Text.Contains([Info], "A1") or Text.Contains([Info], "A2")) then let // 筛选同Col1+Col2且满足R+B条件的行 matchedRows = Table.SelectRows(#"HELPER QUERY", (row) => row[Col1] = [Col1] and row[Col2] = [Col2] and row[#"I/R"] = "R" and Text.Contains(row[Info], "B") ) in if Table.RowCount(matchedRows) > 0 then "Option 1" else "Option 2" else "Other" )
3. 修正方案二:预分组聚合提升效率
如果数据量大,逐行筛选效率低,可以先按Col1+Col2分组,预计算每个组是否满足R+B条件:
// 第一步:创建分组聚合辅助查询 let grouped = Table.Group(#"HELPER QUERY", {"Col1", "Col2"}, { {"HasR_B", each List.AnyTrue(List.Transform(_, (row) => row[#"I/R"] = "R" and Text.Contains(row[Info], "B"))), type logical} }) in grouped // 第二步:主查询合并分组表并标记结果 = Table.NestedJoin(#"Changed Type1", {"Col1", "Col2"}, grouped, {"Col1", "Col2"}, "GroupInfo", JoinKind.LeftOuter) = Table.AddColumn(#"Added Custom", "Outcome", each if ([#"I/R"] = "I") and (Text.Contains([Info], "A1") or Text.Contains([Info], "A2")) then if [GroupInfo][HasR_B]{0} = true then "Option 1" else "Option 2" else "Other" ) = Table.RemoveColumns(#"Added Custom", {"GroupInfo"})
4. 额外优化:简化冗余列
上述方案无需提前创建Helper R和Concat Info列,直接通过原始列判断即可,减少不必要的计算步骤。
内容的提问来源于stack exchange,提问作者Katie Brown
相关产品推荐
相关产品推荐

