在 Power 查询中按最接近的日期和 ID 合并两个表

Merging two tables by the closest date and ID in Power query

我有两个 excel 工作簿,其中包含有关卡车何时离开仓库的信息,以及一个在另一个仓库接收卡车的信息。每个文件在单独的列中包含以下内容:

出发地: 出发日期, 出发时间, 卡车编号, 货物信息

收到: 到达日期, 到达时间, 卡车编号

我如何合并这两个 table,以便接收 table 可以使用 Power Query 填充来自出发 table 的货物?

如您所见,有时同一辆卡车在同一日期的不同行程中,因此,最好根据特定卡车 ID 的最近日期和时间分配货物。很明显,卡车不能在它离开之前到达。

我想尝试使用 Power Query 执行此操作,但我一直在摸索如何操作。非常感谢任何帮助。

我的两个玩具数据文件可以下载here

Powerquery 版本:

加载 Departure table,这里是 Table1 到 Powerquery

将日期列的数据类型转换为日期,将时间列的数据类型转换为时间

let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Time", type time}, {"Truck_ID", type text}, {"Cargo", type text}})
in #"Changed Type"

文件 .. 关闭并加载 .. 仅连接

将 Receive table 加载到 Powerquery

将日期列的数据类型转换为日期,将时间列的数据类型转换为时间

添加列、自定义列

= (i)=> Table.FirstN(Table.Sort(Table.SelectRows(Table1, each [Date] = i[Date] and [Truck_ID] = i[Truck_ID] and [Time]<=i[Time]),{{"Time", Order.Descending}}),1)

这样做是从表 1(出发)中找到具有相同日期、相同卡车 ID 且时间小于或等于接收时间的所有行。然后按时间降序排序,并取第一行,从而找到最接近的时间。

最后,使用添加的新列顶部的箭头展开货物列

Table2 的完整代码(接收 table)

let Source = Excel.CurrentWorkbook(){[Name="Table2"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Time", type time}, {"Truck_ID", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", (i)=> Table.FirstN(Table.Sort(Table.SelectRows(Table1, each [Date] = i[Date] and [Truck_ID] = i[Truck_ID] and [Time]<=i[Time]),{{"Time", Order.Descending}}),1)),
#"Expanded Custom" = Table.ExpandTableColumn(#"Added Custom", "Custom", {"Cargo"}, {"Cargo"})
in  #"Expanded Custom"

应该这样做:

  1. 堆叠表格

  2. 按卡车和时间排序 = Table.Sort(#"替换值",{{"Truck_ID",Order.Descending},{"时间",Order.Descending}})

  3. 添加从1开始的索引列,然后整数除以2

现在可以从这里引用两次了。在一种情况下按到达过滤,在另一种情况下按出发过滤,然后使用索引作为 ID 合并:

这是另一种使用排序和分组来开发列表的方法 代码注释中解释的算法

MCode

let

//Generated by the UI if you select to get Data from Folder
//and the folder has only your tables to process.
//If there are other tables, add a Filter to just select the two you want.
    Source = Folder.Files("C:\Users\ron\Desktop\BillyJo"),
    #"Filtered Hidden Files1" = Table.SelectRows(Source, each [Attributes]?[Hidden]? <> true),
    #"Invoke Custom Function1" = Table.AddColumn(#"Filtered Hidden Files1", "Transform File", each #"Transform File"([Content])),
    #"Renamed Columns1" = Table.RenameColumns(#"Invoke Custom Function1", {"Name", "Source.Name"}),

//Keep only the Source.Name and Transform Files columns
    #"Removed Other Columns1" = Table.SelectColumns(#"Renamed Columns1", {"Source.Name", "Transform File"}),

//Combine the two tables
    combin = Table.Combine(#"Renamed Columns1"[Transform File]),
    #"Changed Type" = Table.TransformColumnTypes(combin,{{"Date", type date}, {"Time", type time}}),

//create dateTime column to more easily compare the times
    fullDate = Table.AddColumn(#"Changed Type","fullDate", each [Date] & [Time], type datetime),

//sort by full date ascending
    #"Sorted Rows" = Table.Sort(fullDate,{{"fullDate", Order.Ascending}}),

//group by Truck_ID, then fill down the Cargo column and extract the Even rows for the Received table
    #"Grouped Rows" = Table.Group(#"Sorted Rows", {"Truck_ID"}, {
        {"all", each Table.AlternateRows(Table.FillDown(_,{"Cargo"}),0,1,1),    
            type table [Date=nullable date, Time=nullable time, Truck_ID=text, Cargo=nullable text, fullDate=datetime]}
    }),

//Remove unneeded column and
//Expand the table produced by the Grouping
    #"Removed Columns" = Table.RemoveColumns(#"Grouped Rows",{"Truck_ID"}),
    #"Expanded all" = Table.ExpandTableColumn(#"Removed Columns", "all", {"Date", "Time", "Truck_ID", "Cargo"}, {"Date", "Time", "Truck_ID", "Cargo"})
in
    #"Expanded all"