---
title: "LookML joins that inflate sums (fan-out) | Metacenta"
description: "A one-to-many Looker join repeats the base view's rows, and its sums inflate unless Looker can correct them. How we find it, and the one-line fix."
url: "https://metacenta.com/rules/lookml-join-fanout-sums"
updated: "2026-10-14"
tokens: 651
---

BI semantic layer · rule lookml-join-fanout-sums

# LookML joins that inflate sums (fan-out)

A Metacenta review checks this under the rule **Sums survive a one-to-many join**. Everything below applies whether or not you ever commission one.

## What this rule checks

For each explore with a join declared `one_to_many` or `many_to_many`, this rule checks the base view's measures. It flags sum, average, count and similar measures when the view has no primary key. It also flags a `type: number` measure that aggregates in its own SQL.

## Why it matters

The total is right when the explore is queried alone. It is inflated as soon as a user adds a field from the joined view. Both numbers reach dashboards under the same name.

## How to fix it

**Stop one-to-many joins inflating Looker totals.** Declare `primary_key: yes` on the base view's key, so Looker can apply symmetric aggregates. Rewrite a `type: number` measure as a native aggregate type, or pre-aggregate it in dbt.

Before:

```lookml
view: orders {
  dimension: order_id {
    sql: ${TABLE}.order_id ;;
  }
  measure: total_revenue {
    type: number
    sql: sum(${TABLE}.amount) ;;
  }
}
```

After:

```lookml
view: orders {
  dimension: order_id {
    primary_key: yes
    sql: ${TABLE}.order_id ;;
  }
  measure: total_revenue {
    type: sum
    sql: ${TABLE}.amount ;;
  }
}
```

## When it is fine to leave

A base view whose measures are all distinct aggregates, such as `count_distinct` or `sum_distinct`, is safe: a fan-out can't inflate them, and we don't flag them. If the join is really `many_to_one`, correct the label instead.

## What we need to check it

The `.lkml` files alone. Only joins that declare `one_to_many` or `many_to_many` are examined. An undeclared or mislabelled join isn't; the relationship rule covers that. A key possibly declared in an unsupplied file isn't treated as missing.

[Ask about a review](https://metacenta.com/enquire?src=rule-lookml-join-fanout-sums&via=md)

## Related pages

- [dbt semantic models reading unbuilt columns](https://metacenta.com/rules/semantic-column-not-built)
- [dbt semantic model keys with no unique test](https://metacenta.com/rules/semantic-primary-entity-unasserted)
- [Looker views reading tables dbt does not know](https://metacenta.com/rules/lookml-view-unbuilt-table)
- [Looker views reading raw dbt sources](https://metacenta.com/rules/lookml-view-reads-raw-source)
- [A sample review, as a client reads it](https://metacenta.com/sample)
- [All published rules](https://metacenta.com/rules)
- [How a review is assessed](https://metacenta.com/standard)
