USERELATIONSHIP()

Learn how USERELATIONSHIP activates an inactive relationship for a single calculation, without changing the model's default relationships.

USERELATIONSHIP()

USERELATIONSHIP() activates a specific inactive relationship for the duration of a single calculation, without changing which relationship is active by default in the rest of the model.

CALCULATE(
    Expression,
    USERELATIONSHIP(Column1, Column2)
)

Why Inactive Relationships Exist

A table can have more than one relationship to another table, but only one can be active at a time — every other relationship between the same two tables is created inactive.

FactSales
   |
   +-- OrderDateKey  -> DimDate[DateKey]   (active)
   +-- ShipDateKey   -> DimDate[DateKey]   (inactive)
   +-- DueDateKey    -> DimDate[DateKey]   (inactive)

This commonly happens with multiple date roles against one date table — order date, ship date, due date — where only one relationship can drive automatic filter propagation.


Basic Example

Sales by Ship Date =
CALCULATE(
    [Total Sales],
    USERELATIONSHIP(FactSales[ShipDateKey], DimDate[DateKey])
)
Default behavior:      Total Sales filters by OrderDateKey (the active relationship)
With USERELATIONSHIP:  This specific measure instead filters by ShipDateKey

The rest of the model, and every other measure, is unaffected — USERELATIONSHIP() only changes which relationship is active inside the CALCULATE() it's used in.

Try it live — pick the month the date slicer is filtered to

OrderDate (active)ShipDate (inactive)Amount
JanuaryJanuary500
JanuaryFebruary300
FebruaryFebruary200
FebruaryMarch400
DimDate slicer selection
Total Sales = CALCULATE(SUM(FactSales[Amount]))

filters by OrderDate — the active relationship

0

Sales by Ship Date = CALCULATE(SUM(FactSales[Amount]), USERELATIONSHIP(FactSales[ShipDateKey], DimDate[DateKey]))

activates ShipDate for just this measure

400

— with the slicer on March, 0 was ordered that month, but 400 actually shipped that month — some of it ordered in a different month entirely. Same fact table, same slicer selection, two genuinely different numbers, because each measure filters through a different relationship.


Multiple Date Roles Example

DimDate
   |
   +-- OrderDateKey (active)   -> "Total Sales"        uses this by default
   +-- ShipDateKey (inactive)  -> "Sales by Ship Date"  activates this explicitly
   +-- DueDateKey (inactive)   -> "Sales by Due Date"   activates this explicitly
Sales by Due Date =
CALCULATE(
    [Total Sales],
    USERELATIONSHIP(FactSales[DueDateKey], DimDate[DateKey])
)

Each measure that needs a different date role gets its own USERELATIONSHIP() call, rather than the model needing three separate date tables.


USERELATIONSHIP vs. Multiple Date Tables

An alternative to inactive relationships is creating a separate date table per role — DimOrderDate, DimShipDate, DimDueDate — each with its own active relationship.

Inactive Relationship + USERELATIONSHIPSeparate Date Table per Role
Model complexityOne date table, several inactive relationshipsMultiple date tables
DAX complexityExplicit USERELATIONSHIP() per measureSimpler measures, no USERELATIONSHIP() needed
Slicer behaviorOne shared date slicer, roles selected via measureSeparate slicer needed per date role

Neither is universally correct — USERELATIONSHIP() keeps the model smaller with one shared date table, while separate date tables make each measure simpler at the cost of more tables and slicers.


Common Mistakes

Forgetting USERELATIONSHIP Only Affects Its Own CALCULATE

Each measure that needs the inactive relationship needs its own USERELATIONSHIP() call — it doesn't change the relationship's active/inactive status in the model globally.

Combining Conflicting Relationships in One CALCULATE

Trying to activate two relationships between the same two tables inside one CALCULATE() produces an error — only one can be active for a given pair of tables at a time, even temporarily.

Building a Whole Model Around Inactive Relationships

If nearly every measure needs a different date role, separate date tables per role are often simpler to maintain than a web of USERELATIONSHIP() calls scattered across the model's measures.


Best Practices

  • Use USERELATIONSHIP() for occasional alternate-date (or alternate-key) calculations, not as the default way every measure resolves its relationships.
  • Name relationship-specific measures clearly ("Sales by Ship Date", not just "Sales 2") so it's obvious which relationship each one activates.
  • Consider separate date tables per role instead, once enough measures need USERELATIONSHIP() that the model becomes hard to follow.

Next Steps

Continue learning DAX functions: