@@ -58,10 +58,10 @@ When the share measure needs to be part of the semantic model — so it is
5858returned by the API, visible in Explore, or accessible to AI agents — define
5959it using multi-stage measures powered by [ Tesseract] [ link-tesseract ] .
6060
61- The key building block is the [ ` group_by ` ] [ ref-group-by ] parameter: when set
62- to an empty list, the inner aggregation stage groups by _ nothing_ , computing
63- the grand total across all rows. The outer stage then joins that total back and
64- groups by the query's dimensions as usual.
61+ The key building block is the [ ` grain ` ] [ ref-grain ] parameter with ` keep_only ` :
62+ when set to an empty list, the inner aggregation stage groups by _ nothing_ ,
63+ computing the grand total across all rows. The outer stage then joins that total
64+ back and groups by the query's dimensions as usual.
6565
6666<Warning >
6767
@@ -76,15 +76,16 @@ Calculating share of total requires three measures:
7676
77771 . A ** base measure** — the regular aggregate, e.g., ` total_sale_price ` .
78782 . A ** helper measure** — a multi-stage measure that re-aggregates the base
79- measure with ` group_by: [] ` , fixing the inner ` GROUP BY ` to nothing (the
80- grand total). This measure is internal and should be hidden from views.
79+ measure with ` grain ` set to ` keep_only: [] ` , fixing the inner ` GROUP BY ` to
80+ nothing (the grand total). This measure is internal and should be hidden from
81+ views.
81823 . A ** ratio measure** — a multi-stage measure that divides the base by the
8283 helper total.
8384
8485The examples below extend the ` order_items ` cube from the
8586[ ecommerce demo model] [ link-ecommerce-demo ] . The ` brand ` and ` category `
8687dimensions are proxied from the joined ` products ` cube so they can be
87- referenced by ` group_by ` .
88+ referenced by ` grain ` .
8889
8990### Share of grand total
9091
@@ -122,7 +123,8 @@ cubes:
122123 multi_stage : true
123124 sql : " {total_sale_price}"
124125 type : sum
125- group_by : []
126+ grain :
127+ keep_only : []
126128
127129 - name : revenue_share
128130 multi_stage : true
@@ -165,7 +167,9 @@ cube(`order_items`, {
165167 multi_stage : true,
166168 sql : ` ${total_sale_price}` ,
167169 type : ` sum` ,
168- group_by : []
170+ grain : {
171+ keep_only : []
172+ }
169173 },
170174
171175 revenue_share : {
@@ -180,7 +184,7 @@ cube(`order_items`, {
180184
181185</CodeGroup >
182186
183- ` group_by : []` tells Tesseract that the inner stage for ` total_revenue_grand_total `
187+ ` keep_only : []` tells Tesseract that the inner stage for ` total_revenue_grand_total `
184188should group by no dimensions, producing a single grand-total row. The outer stage
185189joins it back and groups by whatever dimensions are in the query (e.g., ` brand ` ),
186190so every row receives the same total denominator.
@@ -216,9 +220,9 @@ Sometimes you want each row's share _within a category_ rather than the
216220overall total — for example, each brand's share of its product category's
217221revenue.
218222
219- Use ` group_by ` with the dimension you want to _ fix_ as the subtotal boundary.
220- The inner stage will group only by that dimension, and the outer stage will
221- group by the full set of query dimensions:
223+ Use ` grain ` with ` keep_only ` set to the dimension you want to _ fix_ as the
224+ subtotal boundary. The inner stage will group only by that dimension, and the
225+ outer stage will group by the full set of query dimensions:
222226
223227<CodeGroup >
224228
@@ -256,8 +260,9 @@ cubes:
256260 multi_stage : true
257261 sql : " {total_sale_price}"
258262 type : sum
259- group_by :
260- - category
263+ grain :
264+ keep_only :
265+ - category
261266
262267 - name : revenue_share_of_category
263268 multi_stage : true
@@ -304,7 +309,9 @@ cube(`order_items`, {
304309 multi_stage : true,
305310 sql : ` ${total_sale_price}` ,
306311 type : ` sum` ,
307- group_by : [`category`]
312+ grain : {
313+ keep_only : [`category`]
314+ }
308315 },
309316
310317 revenue_share_of_category : {
@@ -319,7 +326,7 @@ cube(`order_items`, {
319326
320327</CodeGroup >
321328
322- With ` group_by : [category]` , the inner stage computes revenue per category.
329+ With ` keep_only : [category]` , the inner stage computes revenue per category.
323330The outer stage groups by both ` category ` and ` brand ` , so each brand row
324331divides its revenue by the right category total. Exclude
325332` category_revenue_grand_total ` from the view the same way as shown above.
@@ -348,7 +355,7 @@ override)][ref-share-filter].
348355
349356[ link-tesseract ] : https://cube.dev/blog/introducing-next-generation-data-modeling-engine
350357[ link-ecommerce-demo ] : https://github.com/cubedevinc/ecommerce_demo
351- [ ref-group-by ] : /reference/data-modeling/measures#group_by
358+ [ ref-grain ] : /reference/data-modeling/measures#grain
352359[ ref-filter ] : /reference/data-modeling/measures#filter
353360[ ref-share-filter ] : /docs/data-modeling/measures#share-of-total-filter-override
354361[ ref-dynamic-params ] : /recipes/data-modeling/passing-dynamic-parameters-in-a-query
0 commit comments