COUNTIFS in M language over two tables

Marc

My objective is to determine whether certain users have been set up correctly in the finance system.

To determine this, I have a table of users showing their name, team, specific finance role and their permissions, similar to this:
Table name: USERS

| User       | Team | ApprovalRole | UserGroup        |
| ----       | ---- | ------------ | ---------        |
| User One   | ABC  | <75K         | APPROVER         |
| User Two   | ABC  | <1M          | APPROVER         |
| User Three | ABC  | <500K        | BASIC            |
| User Four  | TRD  | POA-1,000    | PO APPROVER      |
| User Five  | TRD  | POA-50,000   | PO APPROVER      |
| User Six   | ZBQ  | INV_APP      | INVOICE APPROVER |
| User Seven | ZBQ  | 0            | BASIC            |
| User Eight | YHW  | 0            | BASIC            |
| User Nine  | YHW  | CEO          | BASIC            |
| User Ten   | YHW  | INVAPP       | INVOICE APPROVER |

I also have a lookup-table which lists the "correct" set-up of the roles which I'm monitoring. Below is a sample table showing the structure:
Table name: LOOKUPS

| RoleName         | Team | ApprovalRole | UserGroup        |
| --------         | ---- | ------------ | ---------        |
| PO Approver      | ABC  | <            | Approver         |
| PO Approver      | TRD  | POA-         | PO Approver      |
| PO Approver      | ZBQ  | CEO          | Approver         |
| Invoice Approver | ZBQ  | INV_APP      | Invoice Approver |
| Invoice Approver | YHW  | INVAPP       | Invoice Approver |

My end-goal is to have a column added to USERS table which identifies whether these types of users are set-up correctly.

APPROACH 1
My preferred approach would be like a COUNTIFS in Excel.
SUM(COUNTIFS(LOOKUPS[Team],[@Team],LOOKUPS[ApprovalRole],[@ApprovalRole]),COUNTIFS(LOOKUPS[Team],[@Team],LOOKUPS[UserGroup],[@UserGroup])).
This will give a score of 0, 1 or 2:

  • 0's I can ignore - they aren't connected to this activity at all;
  • 1's are errors. They either have the ApprovalRole OR they have the UserGroup, but not both. These need to be fixed;
  • 2's are passes - everything is fine so nothing to worry about.

Q1: If I go down this route, can someone provide some help on how best to code these formulae in M language? I've tried to follow the post from JayKilleen but this only works for a single comparision; I need to compare two fields in both parts of my SUM formula.
Q2: I understand M uses case-sensitive coding. I can create a column for LOOKUPS[UserGroup] in capitals. But is there are way to add this into COUNTIFS-equivalent formula so it's done in one step (COUNTIFS reads the field as capitals), rather than two (step one, convert to capitals, step two, run the COUNTIFS)?
Q3: How would I add a wildcard search so User One, User Two, User Four and User Five are correctly identified as a PO Approver?

APPROACH 2
I could merge the two tables together. To do this, I'd need a Lookup-Helper column on each table comprising Team-UserGroup-ApprovalRole.
I don't think this approach would wholly work; this report is going to act as a quality assurance check so needs to highlight errors in the processing. In light of this, User Three and User Nine would not be identified as having a valid UserGroup for the activity in progress.
Nevertheless:
Q4: How can I add a wildcard so that User One, User Two, User Four and User Five are correctly identified as "PO Approver?"
Q5: Can someone suggest how the two tables could be merged? The helper column on LOOKUPS is = Table.AddColumn(#"Added Custom", "Helper", each [Team]&[CapitalUserGroup]&[ApprovalRole]&"*") which includes the * wildcard, but when I try to merge this with USERS, zero lines match. If I extend this to fuzzy matches, User Six and User Ten returns two matches: both of the Invoice Approvers. This also fails to identify User Three and User Nine as possibles.

I'm very new to M and don't know what it can do. Much of my research online has returned results in DAX which isn't helpful.

I'd be extremely grateful for any steer to achieving the goal.

Ron Rosenfeld

If I understand your logic, I think this will do the trick.

  • You are checking to ensure that the Team to which a user is assigned is associated with valid approval and usergroup
    • If I have misunderstood, and the Team is irrelevant, let me know
  • Join the two tables based on Team
  • Ensure that for each, the approval and usergroup in the USERS table starts with the same characters as in the relevant LOOKUPS table.

Please read the comments and examine the applied steps to understand:

let
    Source = Excel.CurrentWorkbook(){[Name="USERS"]}[Content],
    users = Table.TransformColumnTypes(Source,
        List.Transform(Table.ColumnNames(Source), each {_,type text})),

//read Lookups table
    Source2 = Excel.CurrentWorkbook(){[Name="LOOKUPS"]}[Content],
    lookups = Table.TransformColumnTypes(Source2,
        List.Transform(Table.ColumnNames(Source2), each {_, type text})),

//join the two tables based on team
    joined=Table.NestedJoin(users,"Team",lookups,"Team", "joined",JoinKind.LeftOuter),

//check for validities
    validApprovalRole = Table.AddColumn(joined, "Valid Approval Role", each 
        let 
            validRoles = [joined][ApprovalRole],
            foundValidRole = List.Accumulate(
                validRoles,false,(state,current)=> 
                    if state = true then true else Text.StartsWith([ApprovalRole],current,Comparer.OrdinalIgnoreCase))
        in 
            foundValidRole, type logical),

    validUserGroup = Table.AddColumn(validApprovalRole, "Valid UserGroup", each 
        let 
            validGroups = [joined][UserGroup],
            foundValidGroup = List.Accumulate(
                validGroups,false,(state,current)=> 
                    if state = true then true else Text.StartsWith([UserGroup],current,Comparer.OrdinalIgnoreCase))
        in 
            foundValidGroup, type logical),
    #"Removed Columns" = Table.RemoveColumns(validUserGroup,{"joined"})
in
    #"Removed Columns"

enter image description here

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Is UNION ALL of two SELECTs over different tables executed in parallel?

How to join tables from two different databases using sqlalchemy expression language / sqlalchemy core?

Pandas excel like countifs of two dataframes with condition

sql query to get difference of sum over two columns spread across two tables grouped by month

My Update query over two tables doesn't work (MYSQL)

Django bulk update with data two tables over

SQL query in two tables (1-M)

SQLite; view; left join two tables; substitute value dynamically with translation from joined table if there is translation in the given language

How to match conditions from two different tables (R language)

SQL Two duplicate tables copy data over

Split Table rows over two Tables

Complex query over two tables

SQL ranking over two tables

How to iterate over two tables simultaneously

Sorting two tables according to average over past 30 days

select results from two tables but choose one field over another

SQL how percent totals from two tables change over time

SQL joins over more than two tables

Eloquent query to search over two tables

Using countifs() to compare two lists in Excel

DAX Average of Distinct Count Over two tables

iterating over two tables simultaneously in Django Template For Selection - Python Django

Applying a function by looping over two tables

I'm getting errors that leaves two of my database tables empty

BigQuery SQL: How to find missing Values on comparing two tables over date range?

I'm unable to join two tables without a duplicates in mysql

Join two tables and summing over the columns using MySQL joins

Compare values between two tables with over partition criteria

Single SUMIFS and COUNTIFS work, but two SUMIFS and two COUNTIFS do not work