In Tableau, how does TOTAL(COUNTD([Customer])) differ from WINDOW_SUM(COUNTD([Customer]))?
answer
- one reads the marks, one reads the rows
- distinct counts do not add up
- sums hide the difference entirely
- a loyal customer appears in many months
basics
~20 sWINDOW_SUM adds up the distinct counts already computed for each mark, so a customer active in several marks is counted several times. TOTAL re-aggregates the partition's underlying rows with the same aggregation, de-duplicating customers across it.
solid answer
~50 sBoth are table calculations evaluated over the same partition, but they read different inputs. `WINDOW_SUM(COUNTD([Customer]))` adds the values the query already returned — one distinct count per mark — so a customer who ordered in March and April contributes to both and is counted twice. `TOTAL(COUNTD([Customer]))` re-applies the aggregation to the partition's underlying rows, so the distinct count is taken across the whole partition and each customer counts once. For additive aggregations such as SUM the two agree, which is why the difference stays hidden until someone uses COUNTD, AVG or MEDIAN. If you need that de-duplicated number at a grain the view does not show, a level of detail expression such as `{FIXED [Region] : COUNTD([Customer])}` is computed by the data source instead. Whichever you choose, check it against a number you can verify by hand before publishing.
code
text · 8 lines// Adds the per-mark distinct counts: double-counts repeat customers
WINDOW_SUM(COUNTD([Customer]))
// Re-aggregates the partition's rows: each customer counted once
TOTAL(COUNTD([Customer]))
// Computed by the data source at a grain the view need not show
{ FIXED [Region] : COUNTD([Customer]) }go deeper
It is enough to know that a distinct count cannot simply be added across months, and that a yearly unique-customer figure is not the sum of the monthly ones.
Explain that one function combines the values already computed per mark while the other re-aggregates the partition's underlying rows, and name which aggregations make the two diverge.
Recognise this failure on a real dashboard, where the number is plausible rather than obviously broken. Know when a level of detail expression is the better instrument, and verify a distinct-count total against an independently derived figure before it ships.
Treat non-additive metrics as a governance issue: unique users, retention and averages are the numbers most often reported inconsistently across teams, and defining them once upstream is more reliable than trusting each workbook to pick the right function.
## Both are table calculations `TOTAL` and `WINDOW_SUM` are both table calculation functions: they run in Tableau after the query returns, over a partition of the aggregated result. Neither can see data that the view's filters removed, and both are affected by addressing and partitioning settings. What separates them is *what they aggregate*. ## WINDOW_SUM adds the marks `WINDOW_SUM(expr)` takes the value of `expr` as already computed for each mark in the window and adds those values together. With `SUM([Sales])` inside, that is exactly right: sales are additive, so adding monthly totals produces the yearly total. With `COUNTD([Customer])` inside, it is arithmetic on the wrong inputs. Each mark's value is the number of distinct customers *in that mark*. Adding twelve monthly distinct counts produces the number of customer-months with activity, not the number of distinct customers in the year. A loyal customer who buys every month contributes twelve. The result is always greater than or equal to the true distinct count, and it looks entirely plausible. ## TOTAL re-aggregates the partition `TOTAL(expr)` re-applies the aggregation in `expr` to the underlying rows of the whole partition rather than combining the mark-level results. With `COUNTD([Customer])` that means the distinct count is computed once across the partition, so each customer counts once no matter how many marks they appear in. The same distinction shows up with averages. `WINDOW_AVG(AVG([Score]))` averages the per-mark averages, giving every mark equal weight regardless of how many rows sit under it. `TOTAL(AVG([Score]))` averages the partition's underlying rows, weighting by row count. Neither is wrong in general; they answer different questions, and the one you get by accident is rarely the one you meant. ## Where they agree For additive aggregations — SUM, and COUNT in most situations — combining mark-level results and re-aggregating the rows give the same answer. That agreement is why the distinction is a differentiator question rather than a daily concern: most dashboards use SUM, the two functions match, and people conclude they are interchangeable. They are not, and the first non-additive measure exposes it. The useful shorthand: aggregations that survive being combined are safe with WINDOW functions; aggregations that require seeing the raw rows — distinct counts, averages, medians, percentiles — need TOTAL, or a different tool entirely. ## The level of detail alternative A table calculation can only work with what the view returned. When you need a de-duplicated count at a grain the view does not display, or a number that should not shift as the shelves change, use a level of detail expression instead: `{FIXED [Region] : COUNTD([Customer])}` is computed by the data source at region grain and does not depend on the table's shape. The trade-off is the usual one — LOD expressions are computed pre-filter for FIXED and add work to the generated query, while table calculations are free but myopic. ## Verify before you publish This is a family of bugs that produces confident, wrong numbers rather than errors. Before shipping a distinct-count total, check it against a figure you can confirm independently: a small filtered subset, a direct query against the source, or a crosstab exported and counted. The habit costs a few minutes and catches a class of defect that otherwise survives to the board deck. ## What interviewers listen for They want the crisp distinction — combining mark values versus re-aggregating the rows — and the recognition that it only matters for non-additive aggregations. A strong answer names distinct counts, averages and medians as the cases at risk, offers the level of detail alternative when the required grain is not in the view, and admits that the safe move is to verify against a known number rather than trust the function name.
- For which aggregations do the two functions return the same number?Additive ones, principally SUM and ordinary COUNT: combining per-mark results and re-aggregating the underlying rows give the same total. The two diverge for anything that needs to see raw rows — COUNTD, AVG, MEDIAN and percentiles — because a summary of summaries is not the summary of the whole. That is why the bug hides in dashboards until someone adds a distinct count.
- When would you use a FIXED level of detail expression instead of either function?When the required grain is not in the view, or the number must not change as the table's shape changes. `{FIXED [Region] : COUNTD([Customer])}` is computed by the data source at region grain regardless of what is on the shelves, while a table calculation can only work with the marks the query returned. The trade-off is that FIXED is evaluated before dimension filters and adds work to the query.
- How would you sanity-check a distinct-count total before publishing it?Reproduce it a second way and compare. Filter the view to a small period you can count by hand, run the equivalent query directly against the source, or build the same figure with a level of detail expression and check the two agree. These functions fail silently with plausible numbers rather than raising errors, so an independent check is the only reliable defence.
saying these in an interview costs you the question
- Treats the two functions as interchangeable synonyms
- Reports a summed distinct count as unique customers
- Assumes averaging per-mark averages weights rows evenly
- Thinks a distinct count can always be added up later
- Never verifies a summary figure against a known number