Calculating period-over-period changes
Use case
Often, there's a need to calculate a period-over-period change in a metric, e.g., week-over-week or month-over-month growth of clicks, orders, revenue, etc.
Data modeling
In Cube, calculating a period-over-period metric involves the following steps:
- Define a multi-stage measure for the current period.
- Define a time-shift measure that references the current period measure and shifts it to the previous period.
- Define a calculated measure that references these measures and uses them in a calculation, e.g., divides or subtracts them.
Multi-stage calculations are powered by Tesseract, the next-generation data modeling
engine (opens in a new tab). Tesseract is currently in preview. Use the
CUBEJS_TESSERACT_SQL_PLANNER environment variable to enable it.
The following data model allows to calculate a month-over-month change of
some value. current_month_sum is the base measure, previous_month_sum
is a time-shift measure that shifts the current month data to the previous
month, and the month_over_month_ratio measure divides their values:
cubes:
- name: month_over_month
sql: |
SELECT 1 AS value, '2024-01-01'::TIMESTAMP AS date UNION ALL
SELECT 2 AS value, '2024-01-01'::TIMESTAMP AS date UNION ALL
SELECT 3 AS value, '2024-02-01'::TIMESTAMP AS date UNION ALL
SELECT 4 AS value, '2024-02-01'::TIMESTAMP AS date UNION ALL
SELECT 5 AS value, '2024-03-01'::TIMESTAMP AS date UNION ALL
SELECT 6 AS value, '2024-03-01'::TIMESTAMP AS date UNION ALL
SELECT 7 AS value, '2024-04-01'::TIMESTAMP AS date UNION ALL
SELECT 8 AS value, '2024-04-01'::TIMESTAMP AS date
dimensions:
- name: date
sql: date
type: time
measures:
- name: current_month_sum
sql: value
type: sum
- name: previous_month_sum
multi_stage: true
sql: "{current_month_sum}"
type: number
time_shift:
- interval: 1 month
type: prior
- name: month_over_month_ratio
multi_stage: true
sql: "{current_month_sum} / NULLIF({previous_month_sum}, 0)"
type: numberResult
Often, when calculating period-over-period changes, you would also use a
query with a time dimension and granularity
that matches the period, i.e., month for month-over-month calculations:
{
"timeDimensions": [
{
"dimension": "month_over_month.date",
"granularity": "month",
"dateRange": ["2024-01-01", "2025-01-01"]
}
],
"measures": [
"month_over_month.current_month_sum",
"month_over_month.previous_month_sum",
"month_over_month.month_over_month_ratio"
]
}Here's the result: