Power Query重复刷新时自动添加并保留唯一标识首次出现日期
Power Query 动态实现唯一标识首次出现日期方案
一、核心需求拆解
- 基于
RecipeName分组,排序后拼接ICS Group ID和concentration range生成唯一标识列 - 去重得到唯一标识列表
- 数据刷新时自动为每个标识记录首次出现日期,区分新老标识
二、动态实现方案(无需手动添加日期列)
该方案通过缓存历史数据实现首次日期的持久化,避免每次刷新重新计算。
1. 生成唯一标识列
先对原始数据排序保证拼接一致性,再分组生成唯一标识:
let // 加载原始数据表(替换为你的表名) Source = Excel.CurrentWorkbook(){[Name="RawData"]}[Content], // 按RecipeName、ICS Group ID、浓度范围排序,确保拼接顺序固定 SortedData = Table.Sort(Source,{ {"RecipeName", Order.Ascending}, {"ICS Group ID", Order.Ascending}, {"concentration range", Order.Ascending} }), // 分组并拼接ICS Group ID与浓度范围为唯一标识 Grouped = Table.Group(SortedData, {"RecipeName"}, { {"UniqueID", each Text.Combine( Table.TransformColumns(_, { {"ICS Group ID", Text.From}, {"concentration range", Text.From} })[ICS Group ID] & "|" & [concentration range], "; " )} }), // 提取唯一标识并去重 UniqueIDList = Table.Distinct(Table.SelectColumns(Grouped, {"UniqueID"})) in UniqueIDList
2. 创建并维护首次日期缓存
新建一个Excel表格命名为ID_FirstOccurrence_Cache,包含UniqueID(文本型)和FirstOccurrenceDate(日期型)两列,用于存储历史标识的首次出现日期。再创建如下查询实现缓存更新:
let // 获取当前生成的唯一标识列表 CurrentIDs = UniqueIDList, // 替换为第一步的查询名 // 读取缓存表,若不存在则创建空表 Cache = try Excel.CurrentWorkbook(){[Name="ID_FirstOccurrence_Cache"]}[Content] otherwise Table.FromRecords({}), // 合并当前标识与缓存数据 Merged = Table.NestedJoin(CurrentIDs, {"UniqueID"}, Cache, {"UniqueID"}, "CacheData", JoinKind.LeftOuter), // 生成首次出现日期:缓存存在则沿用历史日期,新标识用当前日期 AddedDate = Table.AddColumn(Merged, "FirstOccurrenceDate", each if [CacheData] <> null then [CacheData][FirstOccurrenceDate]{0} else DateTime.Date(DateTime.LocalNow()) ), // 清理冗余列并调整数据类型 CleanedTable = Table.TransformColumnTypes( Table.RemoveColumns(AddedDate, {"CacheData"}), {{"UniqueID", type text}, {"FirstOccurrenceDate", type date}} ), // 更新缓存表(需将此查询加载到Excel并覆盖原ID_FirstOccurrence_Cache表) UpdatedCache = CleanedTable in UpdatedCache
3. 关键注意事项
- 缓存表必须保持持久化存储(Excel表或Power BI数据集),否则刷新后历史日期会丢失
- 排序步骤不可省略,否则同一组数据可能因顺序不同生成不同的
UniqueID - 若使用Power BI,可将缓存表存储在数据集或外部CSV文件中,实现跨刷新的持久化
三、简化方案(手动添加日期列)
如果无需严格持久化历史数据,可在原始数据加载时自动添加当前日期列,再分组取最小日期作为首次出现日期:
let Source = Excel.CurrentWorkbook(){[Name="RawData"]}[Content], // 添加当前加载日期列 AddedLoadDate = Table.AddColumn(Source, "LoadDate", each DateTime.Date(DateTime.LocalNow())), SortedData = Table.Sort(AddedLoadDate,{ {"RecipeName", Order.Ascending}, {"ICS Group ID", Order.Ascending}, {"concentration range", Order.Ascending} }), Grouped = Table.Group(SortedData, {"RecipeName"}, { {"UniqueID", each Text.Combine( Table.TransformColumns(_, { {"ICS Group ID", Text.From}, {"concentration range", Text.From} })[ICS Group ID] & "|" & [concentration range], "; " )}, {"FirstOccurrenceDate", each List.Min([LoadDate])} }), UniqueIDWithDate = Table.Distinct(Table.SelectColumns(Grouped, {"UniqueID", "FirstOccurrenceDate"})) in UniqueIDWithDate
该方案缺点是:若原始数据中删除了早期记录,首次日期会被更新为剩余记录的最小日期,无法保留真实的首次出现时间。
内容的提问来源于stack exchange,提问作者Michael Molnár




