Home› Data Analytics› Complete Guide
Complete Guide

Complete Data Analytics Tutorial

This complete guide covers all 15 Data Analytics tutorials on TheCodeForge, organised by topic.

Learning Roadmap
Beginner → Build a strong foundation
Intermediate → Deepen your understanding with practical topics
Advanced → Master advanced concepts and real-world applications
15
Topics
10
Beginner
5
Intermediate
0
Advanced
Jump to section
Power BI (7)Tableau (5)Excel (3)

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.

Context is the whole subject

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 columnMeasure
EvaluatedOnce, at data refreshEvery time a visual renders
Has row contextYes — the row it is being written intoNo, unless an iterator creates one
Sees slicers and visual filtersNoYes — that is the point
CostsStorage in the model, on every rowCPU at query time
Right forStatic attributes: a category, a flag, a bucketAnything 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.

'A single value cannot be determined' — the most useful error in DAX

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.

dax
-- Fails on any row that groups more than one product
Margin % = ( Sales[Price] - Sales[Cost] ) / Sales[Price]

-- Aggregate first, then divide: correct at every grain, including totals
Margin % =
DIVIDE(
    SUM( Sales[Price] ) - SUM( Sales[Cost] ),
    SUM( Sales[Price] )
)

-- When the per-row margin genuinely is the unit of interest,
-- iterate explicitly and say so:
Avg Row Margin % =
AVERAGEX(
    Sales,
    DIVIDE( Sales[Price] - Sales[Cost], Sales[Price] )
)
In practiceDIVIDE 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.

Relationships, joins and blends decide your numbers before any formula runs

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:

TechniqueHappensChoose it when
Join (physical)In the query, before aggregationRows 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 visualTables have different grains and you want each measure aggregated in its own table, then aligned
Blend (Tableau secondary)After aggregation, on the linking fieldsThe second source cannot be joined — different database, different grain — and the linking field is clean on both sides
Union / appendRow-wise, same columnsTwo 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.

Refresh failures are credentials and gateways, almost every time

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.

In practiceIf a refresh started failing on a date nobody changed the report, check password rotation and gateway auto-update before you open the model. Scheduled refresh breaks on calendars, not on logic.

Frequently Asked Questions

Measure or calculated column — how do I decide quickly?
Ask whether the value should change when a user clicks a slicer. If yes, it must be a measure. If it is a fixed attribute of the row — a size bucket, a flag, a cleaned-up category — a calculated column is correct and cheaper at query time. Anything involving a ratio or a share of a total is a measure, because both halves of the ratio have to respond to the same filters.
Why does DirectQuery reject functions that work fine in Import mode?
Because DirectQuery has to translate your DAX into SQL the source database can run. Functions with no SQL equivalent — several time intelligence functions, anything needing a full table scan in memory — cannot be translated, so the engine refuses rather than silently changing the semantics. The options are a composite model with the affected tables imported, a calculation pushed down into a view, or accepting Import mode for that table.
What actually causes a circular dependency in a calculated column?
Two calculations that each need the other's result, often indirectly through 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.
Why does my Tableau LOD expression give the wrong grand total?
Because 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.
Is Excel's #SPILL! error a bug in my formula?
No — it means the formula returned an array that had nowhere to go. Something is occupying the cells the result needs, the result would cross a table boundary, or the range is unbounded such as a whole-column reference inside a dynamic array. Clear the blocking cells or bound the range. It is a layout conflict, not a calculation error, which is why the formula looks perfectly correct.
Do I need to learn SQL to be good at BI tools?
Yes, and earlier than most people expect. Every error in this track about grain, duplication and relationships is a join problem in disguise, and the engineers who debug those quickly are the ones who can picture the intermediate result set. The tools will let you avoid SQL for a while; they will not let you avoid the concepts.

Power BI

Tableau

Excel

Also Explore
Database 139 tutorials → Python 171 tutorials → System Design 145 tutorials → Interview 77 tutorials → Data Engineering 13 tutorials → ML / AI 206 tutorials →
Start from the beginning

Every tutorial starts with a plain-English analogy — then real code, then interview questions.

Browse Data Analytics Tutorials →