# DAX Many-to-One Side Calculations

Anyone who has constructed or maintained data modes for databases or Business Intelligence applications knows the importance of “one-to-many” relationships.

This would allow you to do something like look up a part number and determine how many of that part has been sold.

But what if you want to answer a question that is posited in a reverse way, such as “How many customers do I have in Austria versus the United States?”

This would require the use of a “many-to-one” relationship.

There are many (*no pun intended*) ways of creating this relationship; each has its impact level on your analysis.

Let’s look at some of the more common methods for performing “many-to-one” lookups.

This tutorial will demonstrate methods using Excel’s Power Pivot Data Model, but the same applies when working with Power BI or most any other Business Intelligence or database application.

Below is a snapshot of a data model that has four tables: “**Sales**” which is our __Fact Table__ and three __Dimension Tables__ called “**dCustomer**”, “**dProduct**”, and “**Calendar**”.

The connections between the tables are as follows:

**[CustNum]**connects “**dCustomer**” and “**Sales**”**[ProductNum]**connects “**dProduct**” and “**Sales**”**[Date]**connects “**Calendar**” and “**Sales**”

Here is the million-dollar question:

### “How many different cities are we selling to each month?”

We need to create a distinct list of customer cities by month.

Something that looks like the following.

# Think About This Process

When we filter the “**Calendar**” table by a month (ex:* “Jan-2021”*), the filter flows to the “**Sales**” table and filters all entries by that month.

This process would repeat for each month-year in the “**Calendar**” table. The “**Sales**” table would render a new result for each filter passed from the “**Calendar**” table.

Filters flow from the “one” side of the relationship to the “many” side.

Continuing with the “Jan-2021” example, if we filtered the “**Sales**” table to only display transactions from “Jan-2021”, we would be presented a list of customer numbers (** [CustNum]**) for that month.

What we need to know is the city that each customer belongs to. This would need to be determined by taking each **[CustNum]** entry and filtering the “**dCustomer**” table.

If every customer hailed from the same city, the answer for “Jan” would be **1**. If they were all from separate cities, the answer would be **6**.

# How NOT to Build a Report

If you didn’t know any better, you’d think you could just build a Pivot Table by placing the **[MMM-YYYY]** field in the ROWS and the **[City]** field in the VALUES and then set the **[City]** field to use a __Distinct Count__ aggregator.

This doesn’t exactly yield the results we were hoping for.

All we receive is a distinct count of cities from the “**dCustomer**” table regardless of any other factors.

The reason our results are all the same value is that there is no direct relationship between the “**Calendar**” table and the “**dCustomer**” table.

The Pivot Table even lets us know that a relationship may be missing to satisfy this report.

We need to include the “**Sales**” table in this conversation to help us filter the “**dCustomer**” table based on the **[CustNum]** field.

# Writing a DAX Measure to Answer the Question

As we can’t just create a relationship between the “**dCustomer**” table and the “**Calendar**” table (*there are no common fields between them*), we will write a DAX formula that will traverse the three tables using the “Sales” table to coordinate the conversation. Let’s call this formula “**Distinct Count of Sales City**”.

The formula is below with an explanation to follow.

=CALCULATE(DISTINCTCOUNT(dCustomer[City] ), Sales)

The **CALCULATE** function can alter our filter context.

The expression that **CALCULATE** will use is the **DISTINCTCOUNT** function. We will get a distinct count of the **[City]** field.

**CALCULATE** will use the filtered “**Sales**” table to further filter the “**dCustomer**” table.

Replacing the **[City]** filed with this newly created Measure, we see the following results:

# Visualizing the Data Differently

To help us understand more clearly how we arrived at these numbers, below is a Pivot Table report that shows the month-year and city names aggregating the quantity by each.

Don’t focus on the “Sum of Quantity” as it is there merely to get the three tables connected. Rather, examine the list of unique cities for each month-year entry.

# “What’s up with that total?”

You may have noticed in the earlier Pivot Table report that the total added up to **11**.

Clearly, 4+3+10 does NOT add to 11.

Just as the entry “Jan-2021” is used to filter the Data Model (*this example results in 3 different cities*), the “**Total Cities**” will filter the Data Model to show a unique list of ALL cities (*that being 11*).

Pivot Table totals do not aggregate the rows above them, rather they aggregate the entire Data Model.

In most cases, these arrive at the same result, but as you can see in this case, they do not.

# Solving the Problem a Different Way

Another way to answer this question would be to create a calculated column in the “**Sales**” table that uses a DAX Measure to perform a lookup operation on the “**dCustomer**” table to bring back the associated **[City]** for each **[CustNum]**. This helper column could then have a distinct count operation run against it to get the desired results.

Our DAX formula in our calculated columns named “**SalesCity**” would appear as follows.

=RELATED(dCustomer[City] )

With this new **[SalesCity]** information in our “**Sales**” table, we can easily derive a distinct count of this new column in a Pivot Table.

If we add this new field to the earlier Pivot Table, we see the same results.

Where the first version is more complicated (*not by much*), it does not add any bulk to the Data Model as everything is calculated in real-time.

The second version is easier to understand and possible implement, the penalty comes with increased size in the Data Model and a decrease in report performance.

# Using the CROSSFILTER Function

If you are up for a challenge, consider using the **CROSSFILTER** function to aid in your quest.

**CROSSFILTER** is a function that acts as a **CALCULATE** modifier.

This means it allows you to change the direction of a filter via a formula (*i.e., through a Measure.*)

For example, consider the below Measure named “**Distinct Sales City (CrossFilter)**”.

As before, we will use the **CALCULATE** function to grab the **[City]** field from the “**dCustomer**” table. This will be examined by the **DISTINCTCOUNT** function.

The filter, however, will utilize the **CROSSFILTER** function. **CROSSFILTER** needs to know the two fields (*one from each table*) that are used to connect the tables. For us, those are the “**Sales[CustNum]**” and “**dCustomer[CustNum]**” fields.

The filter direction is set to “Both” so we can send filters in both directions, not just from the “one” to the “many” side.

Adding this new Measure to our existing report shows the following:

Notice that the “Total Cities” for the latest Measure is different.

This anomaly was because we have a city in the “**dCustomer**” table that did not have a sale entry in the “**Sales**” table.

Passing the unfiltered “**Sales**” table to the “**dCustomer**” table effectively says, “don’t filter the destination table in any way”. Thus, we have a full list of customers to count whether or not they made a purchase and show up in the “Sales” table.

## Practice Workbook

Feel free to Download the Workbook HERE.