Power BI Essentials: Relationships, Cardinality, and Filter Direction

Capítulo 7

Estimated reading time: 10 minutes

+ Exercise

Why relationships matter: they control how filters and totals behave

In Power BI, a relationship is not just a link between tables; it is the mechanism that propagates filters. When you click a slicer, select a bar in a chart, or place fields in a visual, Power BI applies filters to one table and then pushes those filters across relationships to other tables. The direction and type of relationship determine which tables get filtered and how calculations evaluate.

Think of a relationship as a “filter pipe” between two columns. If the pipe is open in one direction, filters flow one way. If it is open in both directions, filters can flow both ways, which can be useful but also risky because it can create ambiguous paths and unexpected totals.

Core idea: filter context follows relationship rules

  • Single-direction relationships are the default in star schemas: filters flow from a dimension (lookup) table to a fact table.
  • Both-direction relationships allow filters to flow back from fact to dimension (and onward), which can change totals and create ambiguity.
  • Cardinality (one-to-many vs. many-to-many) determines whether Power BI can assume a unique “one side” and how it aggregates when duplicates exist.
  • Active vs. inactive relationships determine which path is used by default when multiple relationships exist between the same tables.

Creating relationships: a practical step-by-step workflow

Step 1: identify the join columns and confirm uniqueness expectations

Before creating a relationship, decide which table should be the “one” side (unique keys) and which should be the “many” side (repeated keys). Typical patterns:

  • Dimension table: one row per entity (Customer, Product, Date).
  • Fact table: many rows per entity (Sales transactions, Orders, Line items).

Rules of thumb:

  • If you expect one row per key in a table, that table should be the one side.
  • If you see duplicates for a key, it cannot be the one side unless you fix the data or create a proper dimension.

Step 2: create the relationship in Model view

In Model view, you can create relationships by dragging a key column from one table to the matching key column in another table, or by using Manage relationships > New.

Continue in our app.
  • Listen to the audio with the screen off.
  • Earn a certificate upon completion.
  • Over 5000 courses for you to explore!
Or continue reading below...
Download App

Download the app

When the dialog opens, set:

  • Table / Column on each side (the matching keys).
  • Cardinality (One-to-many, Many-to-many, One-to-one).
  • Cross filter direction (Single or Both).
  • Make this relationship active (checked unless you intentionally need it inactive).

Step 3: validate the relationship immediately (before building measures)

Do not wait until you have complex DAX. Validate filtering behavior with small visuals first (a routine is provided later in this chapter).

Choosing cardinality: one-to-many vs. many-to-many (and why it changes results)

One-to-many (recommended default)

One-to-many is the standard for a clean model: a unique dimension key filters many fact rows. This is predictable and performs well.

Example:

  • DimProduct[ProductID] (unique) 1* FactSales[ProductID] (repeated)

What you get:

  • Product slicers filter sales correctly.
  • Totals are stable because there is a single, unambiguous path from dimension to fact.

Many-to-many (use only when you understand the trade-offs)

Many-to-many means both sides can contain duplicates of the join key. Power BI cannot treat either side as a pure lookup. This can be valid, but it often introduces double-counting risk and confusing filter propagation.

Common legitimate scenarios:

  • Bridge tables for tagging/categorization (Products can have multiple Tags; Tags apply to multiple Products).
  • Shared keys that are not unique due to business reality (e.g., “AccountCode” reused across subsidiaries without a unique company key).

Rules of thumb for many-to-many:

  • Prefer creating a bridge table with unique keys and using two one-to-many relationships instead of a direct many-to-many between large tables.
  • If you must use many-to-many, validate totals carefully and expect that some visuals may behave differently than in a strict star schema.
  • Be explicit about what a “total” means when duplicates exist on both sides.

Quick diagnostic: when cardinality is wrong

  • If Power BI forces many-to-many but you expected one-to-many, your supposed “one” side likely has duplicates or blanks.
  • If totals look inflated, you may be multiplying rows through an unintended many-to-many path.

Cross filter direction: single vs. both (how to choose safely)

Single direction (default and safest)

Single-direction filtering typically flows from dimension to fact. This keeps the model predictable and prevents accidental filter loops.

Use single direction when:

  • You have a star schema (dimensions around facts).
  • You want slicers from dimensions to filter facts, but not the other way around.
  • You have multiple facts and shared dimensions and want to avoid ambiguous paths.

Both direction (powerful, but can create ambiguity)

Both-direction filtering allows a filter applied to either table to propagate to the other. This can be helpful for certain analysis patterns, but it can also:

  • Create ambiguous filter paths (Power BI cannot decide which route to use).
  • Cause unexpected totals because filters can “bounce” through the model.
  • Make visuals sensitive to field placement (small changes in a visual can change the filter context dramatically).

Use both direction only when you can clearly explain why you need it, such as:

  • Analyzing across two fact-like tables through a bridge where you want selections to propagate across.
  • Implementing a controlled many-to-many tagging model where users slice by Tag and expect cross-highlighting across related entities.

Rules of thumb:

  • Start with Single. Switch to Both only to solve a specific filtering requirement you can reproduce and test.
  • Avoid using Both on multiple relationships that could form loops.
  • If you need Both, consider whether a dedicated bridge table plus single-direction relationships can achieve the same outcome more safely.

Active vs. inactive relationships: why your filters sometimes “don’t work”

Only one relationship between two tables can be active at a time. If there are multiple possible relationships (for example, Order Date vs. Ship Date to the same Date table), Power BI will keep one active and set the others inactive.

What this means in practice:

  • Visuals and implicit filtering use the active relationship automatically.
  • An inactive relationship will not filter unless you explicitly activate it in a calculation (typically via DAX).

Modeling rule of thumb:

  • Keep one “default” date relationship active (often Order Date).
  • Keep alternate date relationships inactive and only use them intentionally in measures.

Troubleshooting playbook

Problem 1: ambiguous paths (Power BI warns about ambiguity or visuals behave inconsistently)

Symptoms:

  • You see an error/warning about ambiguous relationships.
  • Totals change unexpectedly when you add/remove a field from a visual.
  • Slicers filter some visuals but not others in surprising ways.

Common causes:

  • Multiple routes exist between tables (loops), often created by enabling Both-direction filters in several places.
  • Two dimensions both connect to the same fact, and also connect to each other (directly or via another table), creating multiple filter paths.

Fix steps:

  • In Model view, trace the paths between the affected tables. Look for loops.
  • Change cross filter direction back to Single on relationships that do not require Both.
  • If you truly need cross-filtering, introduce a bridge table to control propagation rather than turning on Both everywhere.
  • Deactivate one of the competing relationships if two active paths exist (only one should be active for a given filtering purpose).

Problem 2: unexpected totals (too high, too low, or non-additive behavior)

Symptoms:

  • Grand totals do not match the sum of visible rows.
  • Totals look inflated when slicing by a field from a table involved in many-to-many.

Common causes:

  • Many-to-many relationships causing row duplication effects.
  • Both-direction filtering causing filters to propagate in unintended ways.
  • Using a descriptive column from a table that is not a true dimension (not unique), which creates repeated labels and confusing aggregation.

Fix steps:

  • Confirm which table is on the “one” side. If the “one” side has duplicates, create a proper dimension (unique list) and relate through it.
  • Replace direct many-to-many with a bridge pattern when possible.
  • Temporarily set cross filter direction to Single and re-test totals to see if Both-direction is the driver.
  • Validate with a row-level table preview (see validation routine) to detect duplication.

Problem 3: relationship inactivity (filters don’t apply even though keys match)

Symptoms:

  • A slicer from a dimension does not filter a fact as expected.
  • A date slicer filters by Order Date but not by Ship Date (or vice versa).

Common causes:

  • The relationship you expect to be used is inactive.
  • There are multiple relationships between the same tables and the wrong one is active.

Fix steps:

  • Open Manage relationships and check which relationship is active.
  • Decide which should be the default and set it active.
  • Keep alternate relationships inactive and plan to activate them only inside specific measures when needed.

Validation routine: confirm filtering with small visuals before writing calculations

Use this routine whenever you create or modify relationships. The goal is to verify that filters flow exactly as intended using simple, pivot-style checks.

Routine A: dimension-to-fact filter check (single direction expected)

  • Create a Table visual with: Dimension[Name] and a basic numeric field from the fact (e.g., Fact[Amount] as Sum).
  • Add a slicer for Dimension[Name]. Select a single value.
  • Confirm: the table shows only that dimension value and the fact sum changes accordingly.
  • Add a second slicer from a different dimension (e.g., DimDate[Year]) and confirm both slicers reduce the fact sum as expected.

Routine B: key integrity preview (spot duplicates and blanks)

  • Create a Table visual showing the relationship key from the supposed one-side table (e.g., DimProduct[ProductID]).
  • Turn on totals and add a count of rows (use the built-in row count if available, or add any field and set to Count).
  • Scan for blanks and duplicates (duplicates indicate the table is not truly a lookup).
  • If you suspect duplicates, add the descriptive column (e.g., Product Name) next to the key to see if multiple names map to the same key.

Routine C: cross-filter direction sanity check (detect “filter bounce”)

  • Create two slicers: one from a dimension (e.g., DimProduct[Category]) and one from a fact-like attribute (e.g., FactSales[StoreID] if it exists in the fact).
  • With Single direction, selecting a fact attribute slicer should typically not reduce the dimension slicer options (in a classic star schema).
  • If you enable Both, re-test: dimension options may shrink based on fact selections. Confirm this is desired and does not create confusing user experiences.

Routine D: ambiguous path detection with a controlled test

  • Build a simple matrix: Rows = DimA[Name], Columns = DimB[Name], Values = Sum(Fact[Amount]).
  • Apply a slicer from DimA and observe whether the matrix behaves consistently.
  • If values disappear or totals change unexpectedly when you add/remove fields, inspect the model for multiple paths between DimA and DimB through facts/bridges and reduce Both-direction usage.

Routine E: inactive relationship confirmation (date role example)

  • Create two table visuals: both show Fact[Amount] as Sum.
  • Add a slicer for DimDate[Date].
  • In the first visual, include Fact[OrderDate] (or a related field) to confirm the active path filters it.
  • In the second, include Fact[ShipDate] and confirm it does not respond if that relationship is inactive. This confirms your understanding of which relationship is active before you write measures that intentionally use the inactive path.

Practical modeling patterns and rules of thumb

Pattern 1: classic star schema (recommended)

  • Dimensions on the one side, facts on the many side.
  • Single-direction filters from dimensions to facts.
  • Avoid dimension-to-dimension relationships unless there is a clear hierarchy requirement and no alternative.

Pattern 2: bridge for many-to-many (tags, memberships, assignments)

  • Create a bridge table with one row per association (e.g., ProductID–TagID).
  • Relate DimProduct (1→*) Bridge and DimTag (1→*) Bridge.
  • Prefer single-direction from dimensions to bridge; only enable Both if you can justify and validate the cross-filter behavior.

Pattern 3: role-playing dimensions (multiple dates)

  • One Date table, multiple relationships to the fact (Order Date active, Ship Date inactive, etc.).
  • Decide which is the default for most reporting and keep it active.
  • Validate with Routine E so you do not misinterpret slicer behavior.

Now answer the exercise about the content:

You built a star-schema model and notice that selecting a slicer field from a fact-like table unexpectedly reduces the available values in a dimension slicer. Which relationship setting is the most likely cause?

You are right! Congratulations, now go to the next page

You missed! Try again.

Both-direction filtering lets selections on either side propagate across the relationship. In a star schema, this can cause fact selections to shrink dimension slicer options and may lead to unexpected behavior.

Next chapter

Power BI Essentials: Basic DAX Concepts for a Reliable Model

Arrow Right Icon
Free Ebook cover Power BI Essentials: Data Import, Cleaning, and Modeling with Confidence
78%

Power BI Essentials: Data Import, Cleaning, and Modeling with Confidence

New course

9 pages

Download the app to earn free Certification and listen to the courses in the background, even with the screen off.