@@ -10,26 +10,26 @@ revenue, etc.
1010
1111In Cube, calculating a period-over-period metric involves the following
1212steps:
13- - Define a couple of [ ` rolling_window ` measures ] [ ref-rolling-window ] with
14- different windows, i.e., one for _ this period _ and the other for the
15- _ previous period_ .
13+ - Define a [ multi-stage measure ] [ ref-multi-stage ] for the _ current period _ .
14+ - Define a [ time-shift measure ] [ link-time-shift ] that references the current
15+ period measure and shifts it to the _ previous period_ .
1616- Define a [ calculated measure] [ ref-calculated-measure ] that references
17- these ` rolling_window ` measures and uses them in a calculation, e.g.,
18- divides or subtracts them.
17+ these measures and uses them in a calculation, e.g., divides or subtracts them.
1918
2019<WarningBox >
2120
22- Tesseract, the [ next-generation data modeling engine] [ link-tesseract ] , provides a more
23- efficient way to calculate period-over-period changes via [ time-shift measures] [ link-time-shift ] .
24- Tesseract is currently in preview. Use the ` CUBEJS_TESSERACT_SQL_PLANNER `
25- environment variable to enable it.
21+ Multi-stage calculations are powered by Tesseract, the [ next-generation data modeling
22+ engine] [ link-tesseract ] . Tesseract is currently in preview. Use the
23+ ` CUBEJS_TESSERACT_SQL_PLANNER ` environment variable to enable it.
2624
2725</WarningBox >
2826
2927The following data model allows to calculate a month-over-month change of
30- some value. ` current_month_sum ` and ` previous_month_sum ` measures define
31- two rolling windows and the ` month_over_month_ratio ` measure divides
32- their values:
28+ some value. ` current_month_sum ` is the base measure, ` previous_month_sum `
29+ is a time-shift measure that shifts the current month data to the previous
30+ month, and the ` month_over_month_ratio ` measure divides their values:
31+
32+ <CodeTabs >
3333
3434``` yaml
3535cubes :
@@ -53,22 +53,68 @@ cubes:
5353 - name : current_month_sum
5454 sql : value
5555 type : sum
56- rolling_window :
57- trailing : 1 month
58- offset : end
5956
6057 - name : previous_month_sum
61- sql : value
62- type : sum
63- rolling_window :
64- trailing : 1 month
65- offset : start
58+ multi_stage : true
59+ sql : " {current_month_sum}"
60+ type : number
61+ time_shift :
62+ - interval : 1 month
63+ type : prior
6664
6765 - name : month_over_month_ratio
68- sql : " {current_month_sum} / {previous_month_sum}"
66+ multi_stage : true
67+ sql : " {current_month_sum} / NULLIF({previous_month_sum}, 0)"
6968 type : number
7069` ` `
7170
71+ ` ` ` javascript
72+ cube(`month_over_month`, {
73+ sql : `
74+ SELECT 1 AS value, '2024-01-01'::TIMESTAMP AS date UNION ALL
75+ SELECT 2 AS value, '2024-01-01'::TIMESTAMP AS date UNION ALL
76+ SELECT 3 AS value, '2024-02-01'::TIMESTAMP AS date UNION ALL
77+ SELECT 4 AS value, '2024-02-01'::TIMESTAMP AS date UNION ALL
78+ SELECT 5 AS value, '2024-03-01'::TIMESTAMP AS date UNION ALL
79+ SELECT 6 AS value, '2024-03-01'::TIMESTAMP AS date UNION ALL
80+ SELECT 7 AS value, '2024-04-01'::TIMESTAMP AS date UNION ALL
81+ SELECT 8 AS value, '2024-04-01'::TIMESTAMP AS date
82+ ` ,
83+
84+ dimensions : {
85+ date : {
86+ sql : ` date` ,
87+ type : ` time`
88+ }
89+ },
90+
91+ measures : {
92+ current_month_sum : {
93+ sql : ` value` ,
94+ type : ` sum`
95+ },
96+
97+ previous_month_sum : {
98+ multi_stage : true,
99+ sql : ` ${current_month_sum}` ,
100+ type : ` number` ,
101+ time_shift : [{
102+ interval : ` 1 month` ,
103+ type : ` prior`
104+ }]
105+ },
106+
107+ month_over_month_ratio : {
108+ multi_stage : true,
109+ sql : ` ${current_month_sum} / NULLIF(${previous_month_sum}, 0)` ,
110+ type : ` number`
111+ }
112+ }
113+ })
114+ ```
115+
116+ </CodeTabs >
117+
72118## Result
73119
74120Often, when calculating period-over-period changes, you would also use a
@@ -81,22 +127,23 @@ that matches the period, i.e., `month` for month-over-month calculations:
81127 {
82128 "dimension" : " month_over_month.date" ,
83129 "granularity" : " month" ,
84- "dateRange": "this year"
130+ "dateRange" : [ " 2024-01-01 " , " 2025-01-01 " ]
85131 }
86132 ],
87133 "measures" : [
88134 " month_over_month.current_month_sum" ,
89135 " month_over_month.previous_month_sum" ,
90- "month_over_month.change "
136+ " month_over_month.month_over_month_ratio "
91137 ]
92138}
93139```
94140
95141Here's the result:
96142
97- <Screenshot src="https://ucarecdn.com/50c9165a-f15d-491f-86b4-d44009b05576/"/>
143+ <Screenshot src = " https://lgo0ecceic.ucarecd.net/2f97cb29-903c-41ff-99e3-295535d2844f/" />
144+
98145
99- [ref-rolling-window ] : /product/data-modeling/reference/measures#rolling_window
146+ [ ref-multi-stage ] : /product/data-modeling/concepts/multi-stage-calculations
100147[ ref-calculated-measure ] : /product/data-modeling/overview#4-using-calculated-measures
101148[ ref-time-dimension-granularity ] : /product/apis-integrations/rest-api/query-format#time-dimensions-format
102149[ link-tesseract ] : https://cube.dev/blog/introducing-next-generation-data-modeling-engine
0 commit comments