diff --git a/docs/pages/product/data-modeling/concepts/multi-stage-calculations.mdx b/docs/pages/product/data-modeling/concepts/multi-stage-calculations.mdx
index d2b227764d9ab..1ec39239c2b91 100644
--- a/docs/pages/product/data-modeling/concepts/multi-stage-calculations.mdx
+++ b/docs/pages/product/data-modeling/concepts/multi-stage-calculations.mdx
@@ -29,6 +29,7 @@ Common uses of multi-stage calculations:
- [Time-shift](#time-shift) calculations, e.g., year-over-year sales growth.
- [Period-to-date](#period-to-date) calculations, e.g., year-to-date (YTD) analysis.
- [Fixed dimension](#fixed-dimension) calculations, e.g., comparing individual items to a broader dataset or calculating percent of total.
+- [Conditional measure](#conditional-measure) calculations, e.g., based on a dimension value.
- [Ranking](#ranking) calculations.
## Rolling window
@@ -400,6 +401,132 @@ Query and result:
+## Conditional measure
+
+Conditional measure calculations can be used to create measures that depend on the value
+of a dimension. Such measures are defined using the [`case` parameter][ref-case-measures]
+and used together with [`switch` dimensions][ref-switch-dimensions].
+
+```yaml
+- name: amount_in_currency
+ multi_stage: true
+ case:
+ switch: "{CUBE.currency}"
+ when:
+ - value: EUR
+ sql: "{CUBE.amount_eur}"
+ - value: GBP
+ sql: "{CUBE.amount_gbp}"
+ else:
+ sql: "{CUBE.amount_usd}"
+ type: number
+```
+
+### Example
+
+Data model:
+
+
+
+```yaml
+cubes:
+ - name: orders
+ sql: |
+ SELECT 1 AS id, 100 AS amount_usd UNION ALL
+ SELECT 2 AS id, 200 AS amount_usd UNION ALL
+ SELECT 3 AS id, 300 AS amount_usd UNION ALL
+ SELECT 4 AS id, 400 AS amount_usd UNION ALL
+ SELECT 5 AS id, 500 AS amount_usd
+
+ dimensions:
+ - name: currency
+ type: switch
+ values:
+ - USD
+ - EUR
+ - GBP
+
+ measures:
+ - name: amount_usd
+ sql: amount_usd
+ type: sum
+
+ - name: amount_eur
+ sql: "{amount_usd} * 0.9"
+ type: number
+
+ - name: amount_gbp
+ sql: "{amount_usd} * 0.8"
+ type: number
+
+ - name: amount_in_currency
+ multi_stage: true
+ case:
+ switch: "{currency}"
+ when:
+ - value: EUR
+ sql: "{amount_eur}"
+ - value: GBP
+ sql: "{amount_gbp}"
+ else:
+ sql: "{amount_usd}"
+ type: number
+```
+
+```javascript
+cube(`orders`, {
+ sql: `
+ SELECT 1 AS id, 100 AS amount_usd UNION ALL
+ SELECT 2 AS id, 200 AS amount_usd UNION ALL
+ SELECT 3 AS id, 300 AS amount_usd UNION ALL
+ SELECT 4 AS id, 400 AS amount_usd UNION ALL
+ SELECT 5 AS id, 500 AS amount_usd
+ `,
+
+ dimensions: {
+ currency: {
+ type: `switch`,
+ values: [`USD`, `EUR`, `GBP`]
+ }
+ },
+
+ measures: {
+ amount_usd: {
+ sql: `amount_usd`,
+ type: `sum`
+ },
+
+ amount_eur: {
+ sql: `${amount_usd} * 0.9`,
+ type: `number`
+ },
+
+ amount_gbp: {
+ sql: `${amount_usd} * 0.8`,
+ type: `number`
+ },
+
+ amount_in_currency: {
+ multi_stage: true,
+ case: {
+ switch: `${currency}`,
+ when: [
+ { value: `EUR`, sql: `${amount_eur}` },
+ { value: `GBP`, sql: `${amount_gbp}` }
+ ],
+ else: { sql: `${amount_usd}` }
+ },
+ type: `number`
+ }
+ }
+})
+```
+
+
+
+Query and result:
+
+
## Ranking
@@ -471,3 +598,5 @@ Query and result:
[link-cte]: https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL#Common_table_expression
[ref-ref-time-shift]: /product/data-modeling/reference/measures#time_shift
[ref-calendar-cubes]: /product/data-modeling/concepts/calendar-cubes
+[ref-case-measures]: /product/data-modeling/reference/measures#case
+[ref-switch-dimensions]: /product/data-modeling/reference/types-and-formats#switch
\ No newline at end of file
diff --git a/docs/pages/product/data-modeling/reference/measures.mdx b/docs/pages/product/data-modeling/reference/measures.mdx
index 7de4a76b86a21..780c8090d4f9a 100644
--- a/docs/pages/product/data-modeling/reference/measures.mdx
+++ b/docs/pages/product/data-modeling/reference/measures.mdx
@@ -847,6 +847,122 @@ cube(`sales`, {
Named time shifts also allow to reuse the same time shift configuration across multiple
measures and cubes where they are defined.
+### `case`
+
+The `case` parameter is used to define conditional measures, i.e., measures that are
+calculated based on the value of a [`switch` dimension][ref-switch-dimensions].
+
+
+
+`case` measures are powered by Tesseract, the [next-generation data modeling
+engine][link-tesseract]. Tesseract is currently in preview. Use the
+`CUBEJS_TESSERACT_SQL_PLANNER` environment variable to enable it.
+
+
+
+You do not need to include the [`sql` parameter](#sql) if the `case` parameter is used.
+However, the [`multi_stage` parameter](#multi_stage) must be set to `true` for `case`
+measures.
+
+
+
+```javascript
+cube(`orders`, {
+ // ...
+
+ dimensions: {
+ currency: {
+ type: `switch`,
+ values: [
+ `USD`,
+ `EUR`,
+ `GBP`
+ ]
+ }
+ },
+
+ measures: {
+ amount_usd: {
+ sql: `amount_usd`,
+ type: `sum`
+ },
+
+ amount_eur: {
+ sql: `amount_eur`,
+ type: `sum`
+ },
+
+ amount_gbp: {
+ sql: `amount_gbp`,
+ type: `sum`
+ },
+
+ amount_in_currency: {
+ multi_stage: true,
+ case: {
+ switch: `${CUBE.currency}`,
+ when: [
+ {
+ value: `EUR`,
+ sql: `${CUBE.amount_eur}`
+ },
+ {
+ value: `GBP`,
+ sql: `${CUBE.amount_gbp}`
+ }
+ ],
+ else: {
+ sql: `${CUBE.amount_usd}`
+ }
+ },
+ type: `number`
+ }
+ }
+})
+```
+
+```yaml
+cubes:
+ - name: orders
+ # ...
+
+ dimensions:
+ - name: currency
+ type: switch
+ values:
+ - USD
+ - EUR
+ - GBP
+
+ measures:
+ - name: amount_usd
+ sql: amount_usd
+ type: sum
+
+ - name: amount_eur
+ sql: amount_eur
+ type: sum
+
+ - name: amount_gbp
+ sql: amount_gbp
+ type: sum
+
+ - name: amount_in_currency
+ multi_stage: true
+ case:
+ switch: "{CUBE.currency}"
+ when:
+ - value: EUR
+ sql: "{CUBE.amount_eur}"
+ - value: GBP
+ sql: "{CUBE.amount_gbp}"
+ else:
+ sql: "{CUBE.amount_usd}"
+ type: number
+```
+
+
+
### `format`
`format` is an optional parameter. It is used to format the output of measures
@@ -943,3 +1059,4 @@ cubes:
[ref-multi-stage]: /product/data-modeling/concepts/multi-stage-calculations
[ref-time-shift]: /product/data-modeling/concepts/multi-stage-calculations#time-shift
[ref-calendar-cubes]: /product/data-modeling/concepts/calendar-cubes
+[ref-switch-dimensions]: /product/data-modeling/reference/types-and-formats#switch
\ No newline at end of file
diff --git a/docs/pages/product/data-modeling/reference/types-and-formats.mdx b/docs/pages/product/data-modeling/reference/types-and-formats.mdx
index d55347037ce1b..88499c3218c4a 100644
--- a/docs/pages/product/data-modeling/reference/types-and-formats.mdx
+++ b/docs/pages/product/data-modeling/reference/types-and-formats.mdx
@@ -255,7 +255,7 @@ Performs a table count, similar to SQL's `COUNT` function. However, unlike
writing raw SQL, Cube will properly calculate counts even if your query's
joins will produce row multiplication.
-You do not need to include a `sql` parameter for this type.
+You do not need to include the `sql` parameter for the measure of this type.
`drill_members` parameter is commonly used with type `count`. It allows users to
click on the measure in the UI and inspect individual records that make up a
@@ -761,6 +761,64 @@ cubes:
+### `switch`
+
+`switch` type is used to define a dimension that can only take one of the predefined
+set of values. It is similar to an enum type in programming languages. They are
+particularly useful for defining [`case` measures][ref-case-measures].
+
+
+
+`switch` dimensions are powered by Tesseract, the [next-generation data modeling
+engine][link-tesseract]. Tesseract is currently in preview. Use the
+`CUBEJS_TESSERACT_SQL_PLANNER` environment variable to enable it.
+
+
+
+You do not need to include the `sql` parameter for the dimension of this type.
+
+
+
+```javascript
+cube(`orders`, {
+ // ...
+
+ dimensions: {
+ currency: {
+ type: `switch`,
+ values: [
+ `USD`,
+ `EUR`,
+ `GBP`
+ ]
+ }
+ }
+})
+```
+
+```yaml
+cubes:
+ - name: orders
+ # ...
+
+ dimensions:
+ - name: currency
+ type: switch
+ values:
+ - USD
+ - EUR
+ - GBP
+```
+
+
+
+
+
+When `switch` dimensions are queried or introspected using the [`/v1/meta` REST API
+endpoint][ref-meta-api], they are represented as dimensions of type `string`.
+
+
+
### `geo`
`geo` dimension is used to display data on the map. Unlike other dimension types
@@ -1098,4 +1156,7 @@ cubes:
[link-strftime]: https://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
[link-d3-time-format]: https://d3js.org/d3-time-format
[ref-viz-tools]: /product/configuration/visualization-tools
-[ref-apis-support]: /product/apis-integrations/core-data-apis#data-modeling
\ No newline at end of file
+[ref-apis-support]: /product/apis-integrations/core-data-apis#data-modeling
+[link-tesseract]: https://cube.dev/blog/introducing-next-generation-data-modeling-engine
+[ref-case-measures]: /product/data-modeling/reference/measures#case
+[ref-meta-api]: /product/apis-integrations/rest-api/reference#base_pathv1meta
\ No newline at end of file