电源查询:如果满足条件,则查找最小日期
Posted
技术标签:
【中文标题】电源查询:如果满足条件,则查找最小日期【英文标题】:Power query: lookup minimum date if criteria fulfilled 【发布时间】:2017-06-21 01:09:26 【问题描述】:假设我有两列:ID 和 date。我想添加第三列最早日期。此列应在与该行中的 ID 匹配的所有数据中查找最早或最短的日期。它将产生以下内容 - 请参阅 ID 501。我有很多数据,所以需要使用电源查询。公式怎么写?
ID Date Earliest Date
501 01/01/2017 01/08/2015
203 08/06/2015 08/06/2015
304 01/04/2014 01/04/2014
501 01/01/2016 01/08/2015
201 01/02/2015 01/02/2015
501 01/08/2015 01/08/2015
【问题讨论】:
【参考方案1】:对于每一行,您可以通过按此行 [ID] 过滤源表,然后从结果表的 [日期] 列中选择最小值来获得最早的日期。
let
Source = #table(type table[ID=Int64.Type, Date=date],
501,"01/01/2017",
203,"08/06/2015",
304,"01/04/2014",
501,"01/01/2016",
201,"01/02/2015",
501,"01/08/2015"
),
Convert = Table.TransformColumnTypes(Source,"Date", type date),
AddMinDateColumn = Table.AddColumn(Convert, "Earliest Date", (thisrow) => List.Min(Table.SelectRows(Convert, each [ID] = thisrow[ID])[Date]), type date)
in
AddMinDateColumn
【讨论】:
嗨,你能解释一下箭头函数在这里做什么吗?我了解逻辑,即检索当前行值,但不了解语法。谢谢。 @deethreenovice 它在表达式中定义了一个函数。例如,当你在函数中看到each
时,这个参数接受另一个函数。代替each
,您可以定义一个变量,然后编写一个嵌套函数,这些函数为每个处理的项目执行。你可以写(x) => x
,而不是each _
。这里对于定义为thisrow
的每一行,执行了几个嵌套函数:Table.SelectRows()
用于返回带有[ID] = thisrow[ID]
的表,然后[Date]
用于从中获取日期列表。然后List.Min
提取最小日期。希望这会有所帮助。
@deethreenovice 你可以在这一行看到这两个例子。我不得不使用thisrow
,因为each
关键字只能使用一次。表达式Table.SelectRows(Convert, each [ID] = thisrow[ID])
已经使用each
,所以如果你写each [ID] = _[ID]
,这将返回表的所有行,因为每一行的ID 都与它自身进行比较(_[ID]
)。这也可以表示为Table.SelectRows(Convert, (processedRow) => processedRow[ID] = thisrow[ID])
谢谢你——我想我就在那里。因此,当使用接受另一个函数作为参数的函数(例如 TableAddColumn)时,您使用 each
或 (x)=>
声明该函数,并且隐含当前行作为参数传递给它?因此,您可以使用[columnName]
或x[columnName]
访问行中的项目?
@deethreenovice 你应该使用 _[columnName]
和 each
关键字。此外,它不是当前 row,而是当前 item,具体取决于功能。例如,对于列表函数,列表项会在那里传递。【参考方案2】:
如果您不关心 ID 列的顺序,您还可以使用 All Rows 聚合和 Date 列中最短日期的聚合对 ID 执行 Group By。构建器应如下图所示:
您将获得另一个名为 Rows 的列,其中包含原始表格。如果您展开此列以显示日期列,您将获得所需的表格。
【讨论】:
如果你想保留原始的每一行,你需要将它加入到原始表中。如果您只想要每个日期的最早行,那么这是最好的。【参考方案3】:解决方案是将原始数据与自身连接,使用最小聚合计算最早日期。
从名为Query1
的查询中的这个起始数据:
ID,Date
501,01/01/2017
203,08/06/2015
304,01/04/2014
501,01/01/2016
201,01/02/2015
501,01/08/2015
通过以下方式加入数据:组合 > 合并查询(又名“加入”)> 将查询合并为新的(以避免修改 Query1)
每次选择Query1
ID 列,保留默认的左外连接类型:
接下来,选择 Transform > Structured Column > Aggregate,然后选择“Count of Date”(如果 UI 建议最小聚合会更好,但我们可以通过直接触摸代码来解决此问题)。
接下来,打开公式栏(视图 > 布局 > 公式栏)并编辑公式以将 List.Count
替换为 List.Min
。重命名新列,就完成了!
我的完整“M”公式:
查询1:
let
Source = Table.PromoteHeaders(Csv.Document("ID,Date
501,01/01/2017
203,08/06/2015
304,01/04/2014
501,01/01/2016
201,01/02/2015
501,01/08/2015"))
in
Source
合并1:
let
Source = Table.NestedJoin(Query1,"ID",Query1,"ID","NewColumn",JoinKind.LeftOuter),
#"Aggregated NewColumn" = Table.AggregateTableColumn(Source, "NewColumn", "Date", List.Min, "Earliest Date")
in
#"Aggregated NewColumn"
【讨论】:
谢谢,不幸的是我尝试了这个,但是有超过 200 万行数据,2 小时后仍然没有完成:(以上是关于电源查询:如果满足条件,则查找最小日期的主要内容,如果未能解决你的问题,请参考以下文章