Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
4 years ago
Solved

Combining Two Tables with Date & Time

Hey there,

 

I'm new to powerBI.

For my Masterthesis i need to create a PowerBI report.

Therefore i import two different tables.

First Table is manuel created: Has Date & Time of an action 

Second Table is automatic created by a machine: Has Date and Time of the same action, but there can be an difference like 1h between the Time  of those two Tables.

Is there a way to combine them with PowerBI, something like defining a timeslot of an hour around my Time in first Table and then checking if any time value of Second Table fits in it:

If (Time.SecondTable) < (Time.FirstTable +30Min) and (Time.SecondTable) > (Time.FristTable -30min) 

so it checks through the whole table, if there are matches and them combines the data to the right rows?

 

Sincerely,

Jonas

  • I suggest (starting with coilNumber/OrderNumber/Date & Time

    • add a custom column that has a List of each Time at one minute interval during your time frame (1 hour before to 1 hour after)
    • Do an innerJoin between the manual and the machine generated table

    M Code

     

     

    let
    
    //Read in the two tables and set the data types
        Source = Excel.CurrentWorkbook(){[Name="machineTable"]}[Content],
        machineTable = Table.TransformColumnTypes(Source,{{"Date & Time", type datetime}, {"Swapped", type text}, {"Material", type text}},"en-DE"),
    
        Source2 = Excel.CurrentWorkbook(){[Name="manualTable"]}[Content],
        manualTable = Table.TransformColumnTypes(Source2,
            List.Zip({Table.ColumnNames(Source2),{Int64.Type,Int64.Type,DateTime.Type}}),"en-DE"),
    
    //add a custom column with a list of the hour before to hour after at one minute intervals
    // (if times are recorded to the second, could round the times first to the nearest minute,
    //  or make the list at one second intervals)
        #"Added Custom" = Table.AddColumn(manualTable, "machineTime", 
            each List.DateTimes([#"Date & Time"]-#duration(0,1,0,0),
            120,
            #duration(0,0,1,0))),
    
    //expand the list of minutes to rows
        #"Expanded allMinutes" = Table.ExpandListColumn(#"Added Custom", "machineTime"),
    
    //Do an inner join with the machine generated table
        #"Join with Machine Table" = Table.NestedJoin(
            #"Expanded allMinutes","machineTime",machineTable,"Date & Time","joined",JoinKind.Inner),
    
    //expand the Swapped and Material Rows from the joined table
    //  and delete the machineTime Column
        #"Expanded joined" = Table.ExpandTableColumn(#"Join with Machine Table", "joined", {"Swapped", "Material"}, {"Swapped", "Material"}),
        #"Removed Columns" = Table.RemoveColumns(#"Expanded joined",{"machineTime"})
    in
        #"Removed Columns"

     

     

     

     

     

     

     

    Instead of a Join, you could instead add a filtered table in a custom column, where the filter is set to return anything from the machine table that is in the range of +/- one hour, but I suspect the join method will be faster.  If it is slow, then we can try the filter method

     

    Filter Method Code

     

     

    let
    
    //Read in the two tables and set the data types
        Source = Excel.CurrentWorkbook(){[Name="machineTable"]}[Content],
        machineTable = Table.TransformColumnTypes(Source,{{"Date & Time", type datetime}, {"Swapped", type text}, {"Material", type text}},"en-DE"),
    
        Source2 = Excel.CurrentWorkbook(){[Name="manualTable"]}[Content],
        manualTable = Table.TransformColumnTypes(Source2,
            List.Zip({Table.ColumnNames(Source2),{Int64.Type,Int64.Type,DateTime.Type}}),"en-DE"),
        
        #"Added Custom" = Table.AddColumn(manualTable, "Custom", each 
            let 
                tStart = [#"Date & Time"]-#duration(0,1,0,0),
                tEnd = [#"Date & Time"] + #duration(0,1,0,0),
                mt = Table.SelectRows(machineTable, each 
                            ([#"Date & Time"]>=tStart) and ([#"Date & Time"]<=tEnd))
            in 
                mt),
        
        #"Expanded Custom" = Table.ExpandTableColumn(#"Added Custom", "Custom", 
            {"Swapped", "Material"}, {"Custom.Swapped", "Custom.Material"})
    in
        #"Expanded Custom"

     

     

5 Replies

  • mahoneypat's avatar
    mahoneypat
    Microsoft Employee

    This is possible. To get a specific solution from the community, please provide sample data. The best way would be to make a pbix file with mock data in your two tables and provide a link to it here (from Google Drive, OneDrive, etc.). Or insert two tables into your post (not images).

     

    Pat

  • Anonymous's avatar
    Anonymous
    Not applicable
    CoilnumberOrdernumberDate & TimeTime -30 minTime +30min
    72623393321912.11.2021 17:15:0012.11.2021 16:45:0012.11.2021 17:45:00
    76545763542425.11.2021 23:50:0025.11.2021 23:20:0026.11.2021 00:20:00
    52445721401407.01.2022 21:55:0007.01.2022 21:25:0007.01.2022 22:25:00

     

     

    Date & TimeSwappedMaterial
    12.11.2021 17:20:00YesSteel
    25.11.2021 23:45:00YesHardend
    07.01.2022 22:10:00YesAluminum
    23.11.2021 15:10:00YesSteel

     

    Those is a part of the two tables.

    I added the two Columns Time-30mins and Time +30mins so i have a time window of 1h, in which the time of the other table should be. 

     

    A result should look like this: I Need the Coilnumber, the Ordernumber, Date & Time, Swapped and Material in my Solution the rest can be deleted but dont needs to.

    CoilnumberOrdernumberDate & TimeTime -30 minTime +30minTime_newSwappedMaterial
    72623393321912.11.2021 17:15:0012.11.2021 16:45:0012.11.2021 17:45:0012.11.2021 17:20:00YesSteel
    76545763542425.11.2021 23:50:0025.11.2021 23:20:0026.11.2021 00:20:0025.11.2021 23:45:00YesHardend
    52445721401407.01.2022 21:55:0007.01.2022 21:25:0007.01.2022 22:25:0007.01.2022 15:10:00YesAluminum
    • ronrsnfld's avatar
      ronrsnfld
      Super User

      I suggest (starting with coilNumber/OrderNumber/Date & Time

      • add a custom column that has a List of each Time at one minute interval during your time frame (1 hour before to 1 hour after)
      • Do an innerJoin between the manual and the machine generated table

      M Code

       

       

      let
      
      //Read in the two tables and set the data types
          Source = Excel.CurrentWorkbook(){[Name="machineTable"]}[Content],
          machineTable = Table.TransformColumnTypes(Source,{{"Date & Time", type datetime}, {"Swapped", type text}, {"Material", type text}},"en-DE"),
      
          Source2 = Excel.CurrentWorkbook(){[Name="manualTable"]}[Content],
          manualTable = Table.TransformColumnTypes(Source2,
              List.Zip({Table.ColumnNames(Source2),{Int64.Type,Int64.Type,DateTime.Type}}),"en-DE"),
      
      //add a custom column with a list of the hour before to hour after at one minute intervals
      // (if times are recorded to the second, could round the times first to the nearest minute,
      //  or make the list at one second intervals)
          #"Added Custom" = Table.AddColumn(manualTable, "machineTime", 
              each List.DateTimes([#"Date & Time"]-#duration(0,1,0,0),
              120,
              #duration(0,0,1,0))),
      
      //expand the list of minutes to rows
          #"Expanded allMinutes" = Table.ExpandListColumn(#"Added Custom", "machineTime"),
      
      //Do an inner join with the machine generated table
          #"Join with Machine Table" = Table.NestedJoin(
              #"Expanded allMinutes","machineTime",machineTable,"Date & Time","joined",JoinKind.Inner),
      
      //expand the Swapped and Material Rows from the joined table
      //  and delete the machineTime Column
          #"Expanded joined" = Table.ExpandTableColumn(#"Join with Machine Table", "joined", {"Swapped", "Material"}, {"Swapped", "Material"}),
          #"Removed Columns" = Table.RemoveColumns(#"Expanded joined",{"machineTime"})
      in
          #"Removed Columns"

       

       

       

       

       

       

       

      Instead of a Join, you could instead add a filtered table in a custom column, where the filter is set to return anything from the machine table that is in the range of +/- one hour, but I suspect the join method will be faster.  If it is slow, then we can try the filter method

       

      Filter Method Code

       

       

      let
      
      //Read in the two tables and set the data types
          Source = Excel.CurrentWorkbook(){[Name="machineTable"]}[Content],
          machineTable = Table.TransformColumnTypes(Source,{{"Date & Time", type datetime}, {"Swapped", type text}, {"Material", type text}},"en-DE"),
      
          Source2 = Excel.CurrentWorkbook(){[Name="manualTable"]}[Content],
          manualTable = Table.TransformColumnTypes(Source2,
              List.Zip({Table.ColumnNames(Source2),{Int64.Type,Int64.Type,DateTime.Type}}),"en-DE"),
          
          #"Added Custom" = Table.AddColumn(manualTable, "Custom", each 
              let 
                  tStart = [#"Date & Time"]-#duration(0,1,0,0),
                  tEnd = [#"Date & Time"] + #duration(0,1,0,0),
                  mt = Table.SelectRows(machineTable, each 
                              ([#"Date & Time"]>=tStart) and ([#"Date & Time"]<=tEnd))
              in 
                  mt),
          
          #"Expanded Custom" = Table.ExpandTableColumn(#"Added Custom", "Custom", 
              {"Swapped", "Material"}, {"Custom.Swapped", "Custom.Material"})
      in
          #"Expanded Custom"

       

       

      • Anonymous's avatar
        Anonymous
        Not applicable

        Thank you for your help.

        The filter Metho is working for me.