Fixed
Fixed(dim…, expr [, IgnoreFilters])
Evaluates expr grouped by exactly the listed dimensions, then joins the result back to the chart’s grain. Dimensions come first, the expression last (SQX007). Date columns take an inline grain: Fixed(Date.Date:month, …).
Filters just work: unlike Tableau’s FIXED, SquareX Fixed evaluates inside the active filter context — no context-filter promotion needed. When you genuinely want the filter-independent number, add the explicit IgnoreFilters flag as the last argument: in Fixed(Customer.Id, [Revenue], IgnoreFilters) each customer’s value is computed ignoring every user filter, while which customers appear still follows the view (and row-level security always applies).
When the chart is coarser than the Fixed grain, the chart’s field-well aggregation re-aggregates the joined-back values — drop [CustomerRevenue] on a by-region chart with agg avg and you get average revenue per customer per region.
Composes with Calculate, both ways. Wrapping (Calculate(Fixed(…), mods)) evaluates the whole fixed computation — which dim values exist AND their values — under the modified context; removing a dimension makes the fixed value replicate across it, and a DateShift on the wrapper gives prior-period fixed grains. Putting the Calculate (or a measure that is one) inside the body (Fixed(Customer.Id, [WestRevenue])) modifies only the per-dim values — the set of customers still comes from the unmodified context.
When to use it
Section titled “When to use it”- Per-entity values reused at any grouping: revenue per customer, units per store, first/latest order date per account.
- Distinct counts at a pinned grain:
Fixed(Date.Date:month, CountDistinct(...))for customers-per-month. - Denominators pinned to a grain regardless of what the viewer groups by — if the grain should follow the view instead, use
Include/Exclude.
Example
Section titled “Example”CustomerRevenue := Fixed(Customer.Id, [Revenue])
CustomersPerMonth := Fixed(Date.Date:month, CountDistinct(Sales.CustomerId))
// West-only per-customer revenue — chart with avg for "avg revenue// per customer, West only" at any groupingWestRevPerCustomer := Calculate(Fixed(Customer.Id, [Revenue]), Sales.Region = "West")Under the hood
Section titled “Under the hood”The fixed grain computes in its own CTE, then joins back to the chart’s rows:
// On a bar chart grouped by region, field-well aggregation = avgCustomerRevenue := Fixed(Customer.Id, [Revenue])WITH "__sqx_0" AS ( -- revenue per customer, inside the active filters SELECT "Sales"."customer_id" AS "k0", SUM("Sales"."amount") AS "val" FROM "sales" AS "Sales" GROUP BY "Sales"."customer_id")-- each sales row carries its customer's total; the chart's-- field-well aggregation (avg) re-aggregates per regionSELECT "Sales"."region", AVG("__sqx_0"."val") AS "CustomerRevenue"FROM "sales" AS "Sales"LEFT JOIN "__sqx_0" ON "__sqx_0"."k0" = "Sales"."customer_id"GROUP BY "Sales"."region"At a different grain than the chart, the engine inserts a bridge CTE so each customer counts once per group — deliberately not Tableau’s row-replication.
Good to know
Section titled “Good to know”- Join-backs are LEFT JOINs: outer rows with no matching fixed group carry blank and outer re-aggregation skips them.
- In-language re-aggregation (
Avg([CustomerRevenue])) is not expressible yet — aggregation arguments are columns (SQX013); set the aggregation in the chart instead. - A
DateShiftbelongs on aCalculatewrapping theFixed— inside the body it would displace the dim domain and the values inconsistently (SQX010). NestedFixedandYTD/RollingSuminside aFixedbody are also SQX010.