电源查询:如果满足条件,则查找最小日期

Posted

技术标签:

【中文标题】电源查询:如果满足条件,则查找最小日期【英文标题】:Power query: lookup minimum date if criteria fulfilled 【发布时间】:2017-06-21 01:09:26 【问题描述】:

假设我有两列:IDdate。我想添加第三列最早日期。此列应在与该行中的 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 小时后仍然没有完成:(

以上是关于电源查询:如果满足条件,则查找最小日期的主要内容,如果未能解决你的问题,请参考以下文章

如果满足另一个中指定的条件,则更新查询在其中一个中更新数据

如果不满足最小和最大条件,则阻止表单提交

如何跨表格取满足条件的某一列数据的最小日期的函数

查找最大同时出现次数,如果满足条件则增加变量

mysql如果条件满足则执行join否则不

php框架 laravel 多重条件查询。对数据库查询,在满足日期范围查询的同时在满足一个或几个条件查询。