You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: references/joins.mdx
+65-2Lines changed: 65 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -514,7 +514,70 @@ There are a few situations where Lightdash doesn't currently handle inflated met
514
514
- **Metrics that reference joined dimensions**
515
515
- **Complex sequential joins**, e.g one-to-many, one-to-many and then a many-to-one
516
516
- **Custom dimensions** sometimes cause duplicate rows where they shouldn't
517
+
- **Intentional fanouts** where the fanout is desired for business logic (see below)
518
+
519
+
#### Intentional fanouts
520
+
521
+
In some business scenarios, fanouts are actually desired and represent real data relationships. A common example is when you need to calculate per-user fees or charges.
522
+
523
+
##### Example: Per-user billing
524
+
525
+
Consider a scenario with accounts, users, and per-user fees where different accounts pay different rates:
526
+
527
+
**accounts table:**
528
+
| account_id | account_name |
529
+
| :--------- | :----------- |
530
+
| 1 | TechCorp |
531
+
| 2 | StartupXYZ |
532
+
533
+
**users table:**
534
+
| user_id | account_id | user_name |
535
+
| :------ | :--------- | :-------- |
536
+
| 101 | 1 | Alice |
537
+
| 102 | 1 | Bob |
538
+
| 201 | 2 | David |
539
+
540
+
**fees table:**
541
+
| account_id | fee_type | per_user_amount |
542
+
| :--------- | :----------- | :-------------- |
543
+
| 1 | Support Fee | 80.00 |
544
+
| 1 | Training Fee | 120.00 |
545
+
| 2 | Support Fee | 50.00 |
546
+
| 2 | Training Fee | 75.00 |
547
+
548
+
When you join these tables:
549
+
550
+
```sql
551
+
SELECT
552
+
a.account_name,
553
+
u.user_name,
554
+
f.fee_type,
555
+
f.per_user_amount
556
+
FROM
557
+
accounts a
558
+
LEFT JOIN users u ON a.account_id = u.account_id
559
+
LEFT JOIN fees f ON a.account_id = f.account_id;
560
+
```
561
+
562
+
The resulting fanout is exactly what you want for billing:
In this case, each row represents a real charge, and the total billing (TechCorp pays \$400, StartupXYZ pays \$125) is correctly calculated by summing all rows.
574
+
575
+
##### Handling intentional fanouts
576
+
577
+
**Important**: Lightdash does not currently provide a built-in way to explicitly handle intentional fanouts. Using intentional fanouts can cause issues when defining other table relationships and may conflict with Lightdash's automatic fanout handling.
578
+
579
+
**Our recommendation:** Always use fanout protection for joins. When you actually want a fanout (like per-user billing), create a dedicated dbt model that handles the logic and gets your data to the right granularity first. Then use that model in Lightdash.
517
580
518
-
### Warnings
581
+
**How it works:** When fanout handling is enabled for your Lightdash organization, Lightdash warns you about joins that will likely create fanouts. To remove these warnings and enable fanout protection, specify the join relationship and primary keys in your model.yaml file (details [here](#handling-fanouts)).
582
+
This keeps your setup clean and prevents inflated metrics.
519
583
520
-
When fanout handling is enabled, Lightdash will show a warning in the UI for models with joins that probably result in fanouts (and therefore inflated metrics). To remove the errors, `relationship` needs to be defined in the join in YAML and the join key needs to be specified.
0 commit comments