Coming from DAX or Tableau
SquareX deliberately borrows the semantics you already know — measures, filter context, level-of-detail — and spells them in a smaller, plainer syntax. If you can write DAX or LOD expressions, you already think in SquareX; this page maps the vocabulary.
The concept map
Section titled “The concept map”| You know it as | In DAX | In Tableau | In SquareX |
|---|---|---|---|
| Named measures | Measures | (calculated fields) | Name := expr |
| Measure references | [Measure] |
— | [Measure] — same brackets |
| Modify filter context | CALCULATE |
context filters | Calculate(expr, mods…) |
| Remove filters | ALL / REMOVEFILTERS / ALLEXCEPT |
(FIXED, implicitly) | RemoveFilters(dims…) |
| Additive filter | filter args / KEEPFILTERS |
context filters | bare predicates in Calculate |
| Fixed-grain LOD | CALCULATE + ALLEXCEPT patterns |
{FIXED …} |
Fixed(dims…, expr) |
| View-relative LOD | (visual calculations) | {INCLUDE …} / {EXCLUDE …} |
Include / Exclude |
| Same period last year | SAMEPERIODLASTYEAR, DATEADD |
date calcs | DateShift(col, -1, "year") |
| To-date totals | TOTALYTD / QTD / MTD |
RUNNING_SUM table calc |
YTD / QTD / MTD |
| Rolling window | DATESINPERIOD + CALCULATE |
WINDOW_SUM table calc |
RollingSum(expr, n, grain) |
| Iterators | SUMX / AVERAGEX / … |
(row-level calcs) | SumX / AvgX / MinX / MaxX |
| Variables | VAR … RETURN |
— | Let(name, expr, body) |
| Value match | SWITCH |
CASE |
Switch(expr, v, r, …) |
| Searched conditions | SWITCH(TRUE(), …) idiom |
CASE WHEN |
Case(cond, r, … [, default]) |
| Semi-additive (balances) | LASTNONBLANK patterns |
— | LastNonEmpty / PeriodEndSnapshot |
| Safe division | DIVIDE(a, b) (opt-in) |
ZN/manual |
Divide(a, b) — safe by default |
| Row context / context transition | implicit, EARLIER, … |
— | doesn’t exist — deliberately |
The same measure, three dialects
Section titled “The same measure, three dialects”Searched branching — DAX’s most famous workaround, gone:
Revenue Tier =SWITCH(TRUE(), [Revenue] >= 1000000, "Tier 1", [Revenue] >= 100000, "Tier 2", "Tier 3")RevenueTier := Case( [Revenue] >= 1000000, "Tier 1", [Revenue] >= 100000, "Tier 2", "Tier 3")The %-of-total denominator:
Pct of Total = DIVIDE([Revenue], CALCULATE([Revenue], ALL('Product')))PctOfTotal := Divide([Revenue], Calculate([Revenue], RemoveFilters(Product)))Tableau’s fixed LOD:
// Avg revenue per customer (needs the measure wrapped at the sheet level)AVG({ FIXED [Customer Id] : SUM([Amount]) })CustomerRevenue := Fixed(Customer.Id, [Revenue])// …then set the chart's field-well aggregation to avgVariables:
Margin % =VAR rev = [Revenue]RETURN DIVIDE(rev - SUM(Sales[Cost]), rev)MarginPct := Let(rev, [Revenue], Divide(rev - Sum(Sales.Cost), rev))Syntax, side by side
Section titled “Syntax, side by side”Each difference is deliberate — chosen to be easier to read, write, and review:
| Choice | SquareX | DAX / Tableau |
|---|---|---|
| Definition | Name := expr |
DAX Name = expr (vs = comparisons); Tableau calc dialog |
| Column reference | Sales.Amount — plain dotted path |
'Sales'[Amount] / [Table].[Field] |
| Measure reference | [Measure Name] |
[Measure] — the one thing kept identical |
| Date grain | Date.Date:month inline |
DATETRUNC / bucketing boilerplate |
| Logic operators | and · or · not — words |
&& · || · NOT |
| Case sensitivity | case-insensitive, stored canonically | DAX case-insensitive-ish; Tableau case-sensitive fields |
| Division by zero | Divide safe by default |
DAX / gives infinity; DIVIDE is opt-in |
| Comments | // anywhere, survive save |
// and /* */ |
| Function count | 39, curated | ~250+ in DAX |
Habits you get to unlearn
Section titled “Habits you get to unlearn”- Row context and context transition. There is no implicit row context,
no
EARLIER, no wrapping a measure to force context transition. Measures are aggregate-level, full stop; per-row arithmetic happens only inside the iterators, which do not transition context. Row-level logic (per-row labels, flags) lives in calculated fields — a simpler tool that compiles straight into the row SQL. BLANK()arithmetic. SquareX keeps SQL semantics:NULL + 5is NULL — not DAX’sBLANK() + 5 = 5. When you want zeros, say so:Coalesce([Measure], 0). See NULL & type semantics.- Tableau’s FIXED-vs-filters surprise. Tableau evaluates FIXED before
dimension filters, which is why filters “don’t work” on LODs until
promoted to context filters. SquareX
Fixedevaluates inside the active filter context — filters just work. The filter-independent variant is an explicit opt-in flag:Fixed(dims…, expr, IgnoreFilters). - Guessing what a filter argument does. In SquareX a bare predicate in
Calculatealways narrows (intersects) and never overrides; to override you visibly remove then add:Calculate([Revenue], Region = "West", RemoveFilters(Region)). Modifier order is by category (removals first), so the written order can’t bite you. - Table-calc positioning. There are no
WINDOW_SUM-style calcs that depend on the pane layout.YTD,RollingSum, andDateShiftname their date column explicitly and compile into the query — rearranging the visual can’t change the number.
What’s deliberately missing
Section titled “What’s deliberately missing”A few DAX/Tableau capabilities have no SquareX equivalent on purpose:
- A 250-function catalog. The surface is 39 functions. For exotic SQL, use calculated fields (row-level) or the SQL editor — the escape hatch is SQL, not more functions.
- Ranking/window functions (
RANKX,INDEX/OFFSET) — visual-level quick calcs cover ranking today. - Visual calculations — a separate visual-scoped runtime is exactly the kind of second engine SquareX avoids; quick calcs handle per-visual math.
USERELATIONSHIP— the signatureUseRelationship(fromCol, toCol)is reserved for role-playing-date models; it activates when the first model needs it.
If a measure needs something the language refuses, it fails loudly with a diagnostic at the exact position — never a silently different number.
Related
Section titled “Related”- The SquareX guide — the full tour.
- Recipes — the patterns above, ready to paste.
- Filter context & evaluation — the one mental model.