Forum Discussion

memote1's avatar
memote1
Icon for Helper I rankHelper I
1 year ago
Solved

Create a merge column by comparing 3 conditions to a 2nd table (Excel IFS/INDEX(MATCH) to PQ)

I have 2 tables, each contains an ID column and at least 1 email column. I need to get the ID's from PSTable and match to the individuals in TracerTbl. The majority of ID's are the same, but not all,...
  • MarkLaf's avatar
    1 year ago

    I took a stab at this with the below dummy data. The approach is to merge on the columns you are interested in, then, rather than expand on the nested joins, perform a check against the merge column and perhaps pull out the related ID. When multiple rows are joined, we just take the first row and ignore any others, in line with MATCH's behavior (with 0 in last arg) in Excel.

     

    TracerTbl

    Email AddressUserID
    [email protected]1
    [email protected]2
    [email protected]null
    [email protected]4
    [email protected]null
    [email protected]99

     

    PSTable

    IDEmail 1Email 2
    1[email protected][email protected]
    2null[email protected]
    3[email protected][email protected]
    4[email protected]null
    5[email protected][email protected]
    6null[email protected]

     

    Power query (M) in advanced editor:

     

    let
        <...>
        #"Removed Columns1" = <...>,
        MergeOnID = Table.NestedJoin(
            #"Removed Columns1", {"UserID"}, PSTable, {"ID"}, "ID_Check", JoinKind.LeftOuter
        ),
        MergeOnEmail1 = Table.NestedJoin(
            MergeOnID, {"Email Address"}, PSTable, {"Email 1"}, "Email1_Check", JoinKind.LeftOuter
        ),
        MergeOnEmail2 = Table.NestedJoin(
            MergeOnEmail1, {"Email Address"}, PSTable, {"Email 2"}, "Email2_Check", JoinKind.LeftOuter
        ),
        //For each merged column, perform a check calculation
        MergeCheckTransforms = Table.TransformColumns(
            MergeOnEmail2,
            {
                //Gives true/false on whether TracerTbl[ID] was found in PSTable
                {"ID_Check", each not Table.IsEmpty(_), type logical},
                //If no matches found on Email1, return null, otherwise return the ID of first row matched
                {"Email1_Check", each if Table.IsEmpty(_) then null else Table.First(_)[ID], Int64.Type},
                //If no matches found on Email2, return null, otherwise return the ID of first row matched
                {"Email2_Check", each if Table.IsEmpty(_) then null else Table.First(_)[ID], Int64.Type}
            }
        ),
        //Assign validated ID based on matches, with precedent order of: ID, Email1, Email2. 
        //If no matches at all, return null
        AddValidatedId = Table.AddColumn(
            MergeCheckTransforms,
            "Validated ID",
            each
                if [ID_Check] then
                    [UserID]
                else if [Email1_Check] <> null then
                    [Email1_Check]
                else if [Email2_Check] <> null then
                    [Email2_Check]
                else
                    null,
            Int64.Type
        )
    in
        AddValidatedId

     

    Here is the output. You can remove the Check columns or perform whatever other transforms as desired.

     

    Email AddressUserIDID_CheckEmail1_CheckEmail2_CheckValidated ID
    [email protected]1TRUEnullnull1
    [email protected]2TRUEnullnull2
    [email protected]nullFALSE363
    [email protected]4TRUE4null4
    [email protected]nullFALSEnull55
    [email protected]99FALSEnullnullnull

     

    Edit: Including screenshot of output as it's a little more readable: