AXEL Relationship Functions
AXEL provides powerful relationship traversal features that allow you to work with data across multiple related forms. These functions enable you to follow relationships between records, aggregate data from related tables, and filter or group data based on related fields.
Overview
In Mars, forms can have relation fields that link to other forms. For example:
- An Orders form might have a
customerfield linking to Customers - A Customers form might have a
regionfield linking to Regions
AXEL's relationship functions let you traverse these connections to access data from related records.
Quick Reference
| Function | Purpose | Example |
|---|---|---|
RELATED() |
Get a single value from a related record | RELATED(Customer[name], VIA(customer)) |
RELATEDTABLE() |
Get all records from a related table | RELATEDTABLE(Orders, VIA(customer)) |
VIA() |
Specify the relationship path to traverse | VIA(customer, region) |
JOIN: LEFT |
Include all records, NULL for orphans (default) | RELATED(Region[name], JOIN: LEFT) |
JOIN: INNER |
Exclude records without relationships | RELATED(Region[name], JOIN: INNER) |
DEFAULT: |
Provide fallback value for orphan records | RELATED(Region[name], DEFAULT: "Unassigned") |
Feature Matrix
| Feature | RELATED | RELATEDTABLE |
|---|---|---|
| Returns single value | Yes | No (returns table) |
| Returns multiple records | No | Yes |
| Supports VIA clause | Yes | Yes |
| Supports JOIN option | Yes | Yes |
| Supports DEFAULT value | Yes | No |
| Use in aggregations | Yes | Yes |
| Use in FILTER | Yes | Yes |
| Use in SUMMARIZE | Yes | Yes |
When to Use Each Feature
Use RELATED when you need:
- A single column value from a related record
- To add a column showing related data (e.g., customer name on orders)
- To filter by a related field's value
- To group results by a related field
Use RELATEDTABLE when you need:
- All matching records from a related table
- To count or sum values from multiple related records
- To aggregate data from a one-to-many relationship
Use VIA when:
- The relationship field name differs from the table name
- You need to traverse multiple relationship hops
- You want explicit control over the traversal path
Use JOIN: INNER when:
- You want to exclude records without relationships
- You're calculating aggregates and want to skip orphans
- NULL values would skew your results
Use DEFAULT when:
- You want a meaningful fallback for orphan records
- You're displaying data and need user-friendly values
- You want "Unassigned" or "Unknown" instead of blanks
Data Model Example
Throughout this documentation, we'll use this example data model:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Orders │────>│ Products │────>│ Categories │────>│ Departments │
│ │ │ │ │ │ │ │
│ - amount │ │ - name │ │ - name │ │ - name │
│ - quantity │ │ - price │ │ - discount │ │ - budget │
│ - date │ │ - stock │ │ │ │ │
│ - product │ │ - category │ │ - department│ │ │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│
│
v
┌─────────────┐ ┌─────────────┐
│ Customers │────>│ Regions │
│ │ │ │
│ - name │ │ - name │
│ - email │ │ - manager │
│ - region │ │ │
└─────────────┘ └─────────────┘
Learn More
Explore each feature in detail:
- VIA Clause - Learn how to traverse single and multi-hop relationships
- JOIN and DEFAULT Options - Handle orphan records gracefully
- RELATEDTABLE Function - Work with multiple related records
- Cross-Table Operations - FILTER, SUMMARIZE, and aggregations with relationships
Quick Examples
Get customer name for each order
ADDCOLUMNS(
[Orders],
"Customer Name", RELATED([Customers][name], VIA(customer))
)
Get region name (2-hop traversal)
RELATED([Regions][name], VIA(customer, region))
Count orders per customer with fallback
ADDCOLUMNS(
[Customers],
"Order Count", COUNTX(RELATEDTABLE([Orders], VIA(customer)), 1)
)
Filter orders by region
FILTER(
[Orders],
RELATED([Regions][name], VIA(customer, region)) = "North America"
)
Revenue by department (3-hop aggregation)
SUMMARIZE(
[Orders],
RELATED([Departments][name], VIA(product, category, department)),
"Total Revenue", SUMX([Orders], [amount])
)