Skip to content

Commit

Permalink
docs: Period-over-period recipe (#7696)
Browse files Browse the repository at this point in the history
  • Loading branch information
igorlukanin authored Jan 28, 2024
1 parent f17d6b3 commit e21c8da
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 8 deletions.
7 changes: 4 additions & 3 deletions docs/pages/guides/recipes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ These recipes will show you the best practices of using Cube.

### Data modeling

- [Working around string time dimensions](/guides/recipes/data-modeling/string-time-dimensions)
- [Implementing fiscal year or fiscal quarter dimensions](/guides/recipes/data-modeling/fiscal-year-quarter-dimensions)
- [Calculating period-over-period changes](/guides/recipes/data-modeling/period-over-period)
- [Calculating average and percentiles](/guides/recipes/data-modeling/percentiles)
- [Implementing data snapshots](/guides/recipes/data-modeling/snapshots)
- [Implementing fiscal year or fiscal quarter dimensions](/guides/recipes/data-modeling/fiscal-year-quarter-dimensions)
- [Implementing Entity-Attribute-Value model](/guides/recipes/data-modeling/entity-attribute-value)
- [Implementing data snapshots](/guides/recipes/data-modeling/snapshots)
- [Using different data models for tenants](/guides/recipes/access-control/using-different-schemas-for-tenants)
- [Using dynamic measures](/guides/recipes/data-modeling/using-dynamic-measures)
- [Using dynamic union tables](/guides/recipes/data-modeling/dynamic-union-tables)
- [Working around string time dimensions](/guides/recipes/data-modeling/string-time-dimensions)

### Code reusability

Expand Down
11 changes: 6 additions & 5 deletions docs/pages/guides/recipes/data-modeling/_meta.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
module.exports = {
"string-time-dimensions": "Working around string time dimensions",
"fiscal-year-quarter-dimensions": "Implementing fiscal year or fiscal quarter dimensions",
"dynamic-union-tables": "Using dynamic union tables",
"percentiles": "Calculating averages and percentiles",
"period-over-period": "Calculating period-over-period changes",
"snapshots": "Implementing data snapshots",
"entity-attribute-value": "Implementing Entity-Attribute-Value Model (EAV)",
"fiscal-year-quarter-dimensions": "Implementing fiscal year or fiscal quarter dimensions",
"passing-dynamic-parameters-in-a-query": "Passing dynamic parameters in a query",
"snapshots": "Implementing data snapshots",
"using-dynamic-measures": "Using dynamic measures",
"percentiles": "Calculating averages and percentiles"
"dynamic-union-tables": "Using dynamic union tables",
"string-time-dimensions": "Working around string time dimensions"
}
92 changes: 92 additions & 0 deletions docs/pages/guides/recipes/data-modeling/period-over-period.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
## 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 couple of [`rolling_window` measures][ref-rolling-window] with
different windows, i.e., one for _this period_ and the other for the
_previous period_.
- Define a [calculated measure][ref-calculated-measure] that references
these `rolling_window` measures and uses them in a calculation, e.g.,
divides or subtracts them.

The following data model allows to calculate a month-over-month change of
some value. `current_month_sum` and `previous_month_sum` measures define
two rolling windows and the `month_over_month_ratio` measure divides
their values:

```yaml
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
rolling_window:
trailing: 1 month
offset: end

- name: previous_month_sum
sql: value
type: sum
rolling_window:
trailing: 1 month
offset: start

- name: month_over_month_ratio
sql: "{current_month_sum} / {previous_month_sum}"
type: number
```
## Result
Often, when calculating period-over-period changes, you would also use a
query with a time dimension and [granularity][ref-time-dimension-granularity]
that matches the period, i.e., `month` for month-over-month calculations:

```json
{
"timeDimensions": [
{
"dimension": "month_over_month.date",
"granularity": "month",
"dateRange": "this year"
}
],
"measures": [
"month_over_month.current_month_sum",
"month_over_month.previous_month_sum",
"month_over_month.change"
]
}
```

Here's the result:

<Screenshot src="https://ucarecdn.com/50c9165a-f15d-491f-86b4-d44009b05576/"/>

[ref-rolling-window]: /reference/data-model/measures#rolling_window
[ref-calculated-measure]: /product/data-modeling/overview#4-using-calculated-measures
[ref-time-dimension-granularity]: /product/apis-integrations/rest-api/query-format#time-dimensions-format

0 comments on commit e21c8da

Please sign in to comment.