Power Query批量获取各列首/末非空单元格对应startDate日期
解决Power Query中按QID提取首个/最后非空单元格对应startDate的问题
需求背景
处理1GB+、含20万行1216列的大型CSV数据,需按QID(原Attribute列)分组,获取每个QID下首个非空业务单元格对应的startDate和最后非空业务单元格对应的startDate,输出包含QID、首尾有效日期的表格。已完成数据导入Power Query并将空白单元格替换为null。
之前尝试的问题分析
- List First方法错误:
原代码误用全局Source[startDate],导致取到的是整个表的首个非空日期,而非当前分组内的:= Table.Group(Source, {"Attribute"}, {"Min Date", each List.First(List.RemoveNulls(List.RemoveFirstN(Source[startDate],0))), type nullable datetime}) - List Min/Max方法错误:
直接取分组内startDate的最小/最大值,逻辑与需求不符——最小日期不一定是首个出现的有效日期,最大日期也不一定是最后出现的有效日期:= Table.Group(#"Changed Type", {"Attribute"}, { {"First/Last", (t)=> Date.ToText(List.Min(t[startDate]),"dd/MM/yyyy"" to """) & Date.ToText(List.Max(t[startDate]), "dd/MM/yyyy") }})
正确操作步骤
1. 标记有效行
添加辅助列,标记业务列(需替换为实际要检查的列名)非空的行:
= Table.AddColumn(#"Replaced Value", "IsValid", each not List.IsEmpty(List.RemoveNulls({[业务列名]})))
2. 筛选有效记录
筛选IsValid列为true的行,保留每个QID下的有效数据行(保留原始行顺序)。
3. 分组提取首尾日期
按QID分组,提取每个分组内按原始顺序的首个和最后一个startDate:
= Table.Group(#"Filtered Rows", {"QID"}, { {"First Valid Date", each List.First(_[startDate]), type nullable datetime}, {"Last Valid Date", each List.Last(_[startDate]), type nullable datetime} })
注:
_代表当前分组的子表,确保引用的是分组内的数据,而非全局源表。
4. 日期格式化(可选)
若需生成日期范围字符串,添加自定义列:
= Table.AddColumn(#"Grouped Rows", "Date Range", each Date.ToText([First Valid Date], "dd/MM/yyyy") & " to " & Date.ToText([Last Valid Date], "dd/MM/yyyy"))
关键逻辑说明
- 必须保留原始行顺序,再提取首尾有效日期,而非直接取日期的最小/最大值。
- 分组时需引用分组内的子表(
_),避免误取全局数据。
内容的提问来源于stack exchange,提问作者Rodp
相关产品推荐
相关产品推荐

