首先,我是电源查询的新手,所以我迈出了第一步。但是我需要尝试在工作中提供一些时间,这样我才能获得一些喘息的时间来学习。
我有下表(示例):
Orig_Item Alt_Item
5.7 5.10
79.19 79.60
79.60 79.86
10.10
我需要创建一个循环表并显示最终Alt_Item
的列。结果如下:
Orig_Item Alt_Item Final_Item
5.7 5.10 5.10
79.19 79.60 79.86
79.60 79.86 79.86
10.10
非常感谢
答案 0 :(得分:1)
实际上,这对于第一次Power Query体验来说太复杂了。
如果这是你必须做的事情,那么就这样吧,但你应该意识到你开始的是一项非常艰巨的任务。
小细节:我希望最后的Final_Item为10.10。根据示例,如果Alt_Item为null,则Final_Item将为null。如果这不正确,那么这将是您相应调整下面代码的第一步。
您可以创建一个新的空白查询,在高级编辑器中复制并粘贴此代码(替换默认代码)并将Source调整为您的表名。
let
Source = Table.Buffer(Table1),
AddedFinal_Item =
Table.AddColumn(
Source,
"Final_Item",
each if [Alt_Item] = null
then null
else List.Last(
List.Generate(
() => [Final_Item = [Alt_Item], Continue = true],
each [Continue],
each [Final_Item =
Table.First(
Table.SelectRows(
Source,
(x) => x[Orig_Item] = [Final_Item]),
[Alt_Item = "not found"]
)[Alt_Item],
Continue = Final_Item <> "not found"],
each [Final_Item])))
in
AddedFinal_Item
此代码使用函数 List.Generate 来执行循环。 出于性能原因,在调用List.Generate之前,应始终在内存中缓冲表(Table.Buffer)。
List.Generate是最复杂的Power Query功能之一。
它需要4个参数,每个参数本身就是一个函数。
在这种情况下,第一个参数以()开头,另外3个以每个开头(从上面的大纲中可以清楚地看出:它们是对齐的)。
参数1 定义初始值:包含字段Final_Item和Continue的记录。
参数2 是继续的条件:如果找到了某个项目。
参数3 是每次迭代中的实际转换:搜索Source表(使用Table.SelectRows),其中Orig_Item等于Alt_Item。这包含在Table.First中,它返回第一条记录(如果找到)并接受默认值(如果没有找到),在这种情况下是一个记录,其字段为Alt_Item,值为&#34;未找到&#34;,从此结果返回记录字段[Alt_Item]的值,该值可以是第一个记录的值,也可以是&#34;未找到&#34;来自默认值。
如果值为&#34;未找到&#34;,则继续变为 false ,迭代将停止。
参数4 是将返回的值:Final_Item。
List.Generate返回每次迭代的所有值的列表。只需要最后一个值,因此List.Generate包含在List.Last中。
最后评论:Power Query中很少需要实际循环,我认为应该尽可能避免。但是,在这种情况下,这是一个可行的解决方案,因为您事先并不知道将遇到多少Alt_Item。 List.Generate的替代方法是使用 resursive函数。 List.Accumulate 也接近循环,但迭代次数固定。
答案 1 :(得分:0)
这可以简单地通过自连接来解决,一个开放的问题是您将期望支持多少层间接访问。
假设仅一个间接级别,在Orig_Item上没有重复项,解决方案是:
let
Source = #"Input Table",
SelfJoin1 = Table.NestedJoin( Source, {"Alt_Item"}, Source, {"Orig_Item"}, "_tmp_" ),
Expand1 = ExpandTableColumn( SelfJoin1, "_tmp_", {"Alt_Item"}, {"_lkp_"} ),
ChkJoin1 = Table.AddColumn( Expand1, "Final_Item", each (if [_lkp_] = null then [Alt_Item] else [_lkp_]), type number)
in
ChkJoin1
这可以在常规UI中完成,使用合并查询,然后展开列并添加自定义列。
如果您想支持一个以上级别的间接,请将其转换为被调用X次的函数。对于数据驱动的间接级别,您可以将调用包装在list.generate中,将中间表放在结构化列中,尽管这是PQ的高级级别。