Simple visuals + everyday analogies that explain DAX to everyone — whether you're a business analyst or a developer who's never opened Power BI.
If this helps you finally "get" DAX — drop a ⭐. It helps more people find it.
DAX has millions of Power BI users — and almost all of them hit the same wall: filter context vs row context trips everyone up. Most tutorials are either cryptic function references or 50-page textbooks. This repo explains it with a diagram and one analogy.
Every pattern gives you four things:
- 🧒 A plain-English analogy — so the concept clicks before you see a single formula
- 🖼️ A diagram — so the context flow is visible, not just described
- 🔧 How it actually works — the mechanics, explained like a smart friend over coffee
- 🌍 A copy-paste example — ready to drop into your model
The two hardest concepts in DAX — and how CALCULATE bridges them:
flowchart LR
A[Filter Context] --> B[CALCULATE]
C[Row Context] --> B
B --> D[Measure Result]
style A fill:#dbeafe,stroke:#3b82f6,color:#1f2937
style C fill:#fef3c7,stroke:#f59e0b,color:#1f2937
style B fill:#dcfce7,stroke:#22c55e,color:#1f2937
style D fill:#dcfce7,stroke:#22c55e,color:#1f2937
Filter context comes from slicers, row headers, and CALCULATE. Row context comes from calculated columns and iterator functions. CALCULATE is the only thing that can modify filter context — and the only thing that can convert row context into filter context. Everything else flows from there.
| Pattern | One-liner |
|---|---|
| ➕ SUM vs SUMX | SUM adds up a column; SUMX loops through rows and adds up an expression |
| 🧮 CALCULATE | The one function that changes which filters are active before evaluating an expression |
| 🔍 Filter Context | The invisible set of filters Power BI applies before your measure even starts calculating |
| 📏 Row Context | The "current row" DAX is on when it's looping through a table |
| 🔗 RELATED | Jump from the current row in one table to a value in a related dimension table |
| ⚖️ Measures vs Calculated Columns | Same DAX syntax, two completely different behaviors — one stored, one live |
| 📌 VAR / RETURN | Calculate something once, give it a name, use it as many times as you need |
| Pattern | One-liner |
|---|---|
| 📅 TOTALYTD | The running total from the first day of the year to today's date |
| ⏩ DATEADD | Shift any date range forward or backward by days, months, quarters, or years |
| 📆 SAMEPERIODLASTYEAR | The fastest year-over-year comparison in DAX — one function, done |
| 🗓️ DATESBETWEEN | Return all dates between an explicit start and end — great for custom rolling windows |
| Pattern | One-liner |
|---|---|
| 🏆 RANKX | Rank any item dynamically by any measure — updates automatically with every filter |
| 🔝 TOPN | Return a virtual table containing only the top N rows by any measure |
| 🎯 ALLSELECTED | Remove slicer filters while still respecting filters set on the visual itself |
| 🔀 USERELATIONSHIP | Temporarily activate an inactive relationship inside a single measure |
| 🗄️ Virtual Tables | Tables built in memory by DAX functions — they exist during a calculation, then disappear |
| Pattern | One-liner |
|---|---|
| 🔄 Context Transition | The silent moment when CALCULATE converts your row context into an equivalent filter context |
| 🔁 Circular Dependencies | When a calculated column references a column that references it back — Power BI refuses to save |
| 0️⃣ Blank vs Zero | BLANK means "no data existed." Zero means "data existed and it was zero." DAX treats them differently |
- AI for Beginners — Visual Edition — neural networks, transformers, and LLMs explained with diagrams
- Power BI Data Modeling — Visual Edition — star schemas, relationships, and cardinality finally make sense
See CONTRIBUTING.md — new patterns are always welcome.