This complete guide covers all 15 Data Analytics tutorials on TheCodeForge, organised by topic.
Power BI, Tableau and Excel share a design decision that explains most of the errors in this track: they let you write an expression without stating what it should be evaluated over. A SQL query names its rows. A DAX measure does not — it inherits its rows from wherever it happens to be dropped, and the same formula will return a correct number in a card, a wrong number in a matrix, and an error in a calculated column.
So the messages sound almost philosophical. A single value for column 'X' cannot be determined. Cannot mix aggregate and non-aggregate arguments. Cannot determine relationships between the fields. None of those are syntax complaints. Each one is the engine saying it was handed an expression and no unambiguous set of rows to run it on. Once you read them that way they stop being mysterious and become the most useful errors in the tool.
Power BI evaluates every expression in two contexts at once. Row context is a single row being iterated — what a calculated column always has, and what functions like SUMX create. Filter context is the set of rows surviving the slicers, the visual's own grouping, and any CALCULATE modifiers — what a measure always has.
Almost every confusing DAX result is one of these two being different from what the author assumed. A calculated column cannot see the visual's filters, because it was computed at refresh time, before any visual existed. A measure cannot see 'the current row', because in a total row there isn't one. State those two sentences out loud before debugging and most problems resolve themselves.
| Calculated column | Measure | |
|---|---|---|
| Evaluated | Once, at data refresh | Every time a visual renders |
| Has row context | Yes — the row it is being written into | No, unless an iterator creates one |
| Sees slicers and visual filters | No | Yes — that is the point |
| Costs | Storage in the model, on every row | CPU at query time |
| Right for | Static attributes: a category, a flag, a bucket | Anything that must respond to what the user selected |
The practical rule that falls out of that table: if the answer should change when someone clicks a slicer, it must be a measure. Writing it as a calculated column is not a slower way to get the same result — it is a different, frozen result.
This message means you referenced a column where DAX needed one scalar and got many. It usually appears when a measure written for a detail row is displayed on a subtotal, where the column holds several values and DAX refuses to pick one for you.
The wrong fix is to wrap the column in whatever aggregation silences it. MAX will make the error go away and quietly produce a number nobody can defend. The right fix is to decide what the subtotal means and aggregate to match.
DIVIDE rather than / is not style. DIVIDE takes an explicit alternate result for division by zero and returns BLANK by default, so an empty denominator produces an empty cell instead of an infinity that then poisons every total above it.Tableau's cannot blend secondary data source and Power BI's cannot determine relationships between the fields are the same complaint from two vendors: the model does not contain a path from the thing you are filtering to the thing you are measuring, at the grain you asked for.
This is worth getting right before anything else, because a wrong model produces plausible numbers rather than errors. A join that duplicates rows will silently double a sum; a relationship pointing the wrong way will make a filter do nothing at all. Choose deliberately:
| Technique | Happens | Choose it when |
|---|---|---|
| Join (physical) | In the query, before aggregation | Rows genuinely belong together at the same grain and you accept the row duplication a one-to-many join creates |
| Relationship (logical) | At query time, per visual | Tables have different grains and you want each measure aggregated in its own table, then aligned |
| Blend (Tableau secondary) | After aggregation, on the linking fields | The second source cannot be joined — different database, different grain — and the linking field is clean on both sides |
| Union / append | Row-wise, same columns | Two sources describe the same kind of fact for different periods or regions |
Blending fails most often not because blending is fragile but because the linking field is dirty: trailing spaces, different casing, a code stored as text on one side and a number on the other. Clean the key first; the blend stops being temperamental.
A report that works on the desktop and fails on the service has almost never got a formula problem. The desktop used your Windows identity and your machine's network route; the service has neither. Power BI needs credentials stored on the dataset and, for anything on a private network, an on-premises data gateway with a matching data source definition. Tableau needs embedded credentials on the published data source and a running, correctly-versioned Bridge client for cloud-to-private refreshes.
The diagnostic order is fixed and saves hours: confirm the credential is stored (not just entered once), confirm the gateway or Bridge is online, confirm the data source definition on the gateway matches the server and database names in the file exactly — a difference as small as a hostname versus its fully-qualified form is enough to break the match.
CALCULATE or a relationship. The chain is usually longer than it looks: column A filters on a measure that references column B, which was itself derived from A. Power BI detects the loop at model level, which is why the error can point at a column you did not just edit. Break it by making one side independent of the model — compute it in Power Query or in the source.FIXED ignores the view's dimensions by design, so the value it computes does not change as you roll up, and a total that sums those unchanged values double-counts. INCLUDE and EXCLUDE are relative to the view and usually behave the way people expect FIXED to. Also check whether the total should be a sum of the LOD values at all — often the correct total is the LOD expression evaluated at the total's own grain.Every tutorial starts with a plain-English analogy — then real code, then interview questions.
Browse Data Analytics Tutorials →