Three tiers
| Tier | Size | Purpose | Where |
|---|---|---|---|
| Learning | 4–100 rows per table | See every row, check every answer by eye, learn the concept without noise | The 14 Northwind datasets below |
| Scenario | Thousands of rows, realistic mess | Real problems: duplicates, late data, currencies, schema changes, conflicting definitions | Company pack and scenario files used by Experience Mode and the tracks |
| Enterprise | 100 thousand to 50 million rows | Design and performance: cardinality, partitions, incremental refresh, aggregations | Generated on your machine |
Every dataset is generated from a fixed seed, so every learner gets identical numbers and every expected result on this site can be checked automatically.
Learning datasets
All 14 tables describe one fictional company, Northwind Outdoors, and join to each other, so any exercise can grow into a full model. "Planted problems" are there to teach you something; the lessons that use them tell you what to look for.
DimDate
- Type
- Date dimension
- Grain
- One day
- Scale
- 90 rows · 12 columns
- Used for
- Time intelligence; replacing it with a full DAX date table
- Planted problems
- Deliberately too short: only 90 days
DimProduct
- Type
- Dimension
- Grain
- One product
- Scale
- 24 rows · 9 columns
- Used for
- Margin, category slicing, discontinued products
- Planted problems
- None: a clean table
DimCustomer
- Type
- Dimension
- Grain
- One customer
- Scale
- 30 rows · 9 columns
- Used for
- Segments, cohorts by join date, loyalty tiers
- Planted problems
- None: a clean table
DimRegion
- Type
- Dimension
- Grain
- One sales region
- Scale
- 4 rows · 6 columns
- Used for
- Region filters, targets, RLS
- Planted problems
- None: a clean table
DimEmployee
- Type
- Parent-child dimension
- Grain
- One employee
- Scale
- 18 rows · 8 columns
- Used for
- PATH hierarchies, RLS by org position
- Planted problems
- None: a clean table
FactSales
- Type
- Transaction fact
- Grain
- One order line
- Scale
- 100 rows · 12 columns
- Used for
- Modeling, DAX, RLS, role-playing dates
- Planted problems
- Returns as negative quantities; OrderDate ≠ ShipDate
FactBudget
- Type
- Periodic fact (plan)
- Grain
- Month × region × category
- Scale
- 48 rows · 6 columns
- Used for
- Budget vs actual at a different grain
- Planted problems
- None: a clean table
FactInventory
- Type
- Periodic snapshot fact
- Grain
- Product × week (each product held in one warehouse)
- Scale
- 80 rows · 5 columns
- Used for
- Semi-additive measures
- Planted problems
- Summing across weeks gives a wrong answer by design
RawOrdersExport (messy)
- Type
- Raw export
- Grain
- One order line, as exported
- Scale
- 30 rows · 9 columns
- Used for
- Power Query cleaning
- Planted problems
- Header junk, mixed date formats, currency symbols, trailing spaces, inconsistent casing, a total row
SurveyWide (unpivot)
- Type
- Wide (pivoted) table
- Grain
- One row per store, one column per month
- Scale
- 12 rows · 7 columns
- Used for
- Unpivot
- Planted problems
- The wrong shape for analysis, on purpose
UserRegionMapping (RLS)
- Type
- Security mapping
- Grain
- User × region
- Scale
- 12 rows · 3 columns
- Used for
- Dynamic RLS
- Planted problems
- Multi-region users and one ALL user
ExchangeRates
- Type
- Rate table
- Grain
- Currency × week (Mondays)
- Scale
- 39 rows · 3 columns
- Used for
- Last-known-rate currency conversion
- Planted problems
- None: a clean table
CustomerTargets (many-to-many)
- Type
- Target table
- Grain
- Quarter × segment × loyalty tier
- Scale
- 20 rows · 4 columns
- Used for
- Relating facts at a non-unique grain
- Planted problems
- None: a clean table
WebEvents (sessions)
- Type
- Event fact
- Grain
- One click event
- Scale
- 100 rows · 7 columns
- Used for
- Funnels, sessions, window functions
- Planted problems
- None: a clean table
Scenario files
Larger files used by the SQL, warehousing, testing and automation tracks and by the Experience Mode scenarios. The company pack is a realistic order system (orders, lines, returns, customers, products, regions and exchange rates) with real-world defects such as a re-exported batch of duplicate lines.
| File | Rows | What it is |
|---|---|---|
| orders.csv | 3715 | Company pack: one row per order header (Jan 2025 to Mar 2026). |
| order_lines.csv | 7252 | Company pack: order lines in the order currency. Contains the March re-export defect. |
| returns.csv | 343 | Company pack: returns linked to order lines, to 10 Apr 2026. |
| customers.csv | 421 | Company pack: customers with segment and home region. |
| products.csv | 24 | Company pack: the 24 products with cost and list price. |
| regions.csv | 5 | Company pack: five sales regions and their currency. |
| fx_rates.csv | 16 | Company pack: monthly average USD per EUR. |
| customer_changes.csv | 200 | CRM change feed for 120 customers: one row per effective change. Build SCD type 2 from it. |
| early_orders.csv | 4 | Orders that arrive before their customer exists in the dimension. |
| order_events.csv | 907 | Order lifecycle events (Placed, Picked, Shipped, Delivered) for March 2026, in UTC. |
| web_sessions_local.csv | 240 | Web sessions logged in local time with their UTC offset. |
| mini_sales.csv | 8 | Eight hand-checkable sales lines for known-input, known-output model tests. |
| slow_query.sql | The 22-minute source query behind FactSales, with its execution plan summary. | |
| groups.json | Mock GET /groups response: workspaces. | |
| datasets.json | Mock datasets (semantic models) across all workspaces. | |
| reports.json | Mock reports across all workspaces. | |
| refreshes.json | Mock refresh history, one week per dataset. | |
| activity_views.json | Mock activity events (ViewReport) for 90 days. |
Enterprise scale
Small data teaches the logic; big data teaches the design. Generate realistic sales data with skewed customers, late-arriving rows, duplicates, several currencies and slowly changing customers, on your own machine with Node.js:
node tools/generate-enterprise-data.js --rows 1000000| Rows | What it teaches |
|---|---|
| 100 thousand | Everything still works; habits matter more than speed |
| 1 million | Column cardinality and model size become visible in VertiPaq Analyzer |
| 10 million | Incremental refresh and query folding stop being optional |
| 50 million | Aggregations, partitions and capacity limits |
The generator's defects are configurable and counted exactly, so you can check whether your cleaning caught all of them. See the generator guide.
Labs: break it, then fix it
The best way to understand a failure is to cause it on purpose:
| Lab | Break | Then |
|---|---|---|
| Double counting | Append the March file twice | Find it with a row count per key; fix with a distinct key |
| Orphan facts | Delete two products from DimProduct | Find the blank row; count orphans with an anti join |
| Bidirectional chaos | Set every relationship to Both | Watch a total change; explain why |
| Folding | Add an index column before the date filter | See View Native Query disappear; move the step |
| RLS leak | Add a table not related to the security table | Show that a restricted user sees all of it |
| Memory | Add a timestamp column with seconds to the 10M-row table | Measure the size in VertiPaq Analyzer; split date and time |
The testing track's Build it, break it topic turns these into graded assignments.
Scenarios by stage
| Ticket | Scenario | Stage | Skills |
|---|---|---|---|
| BI-1042 | Executive sales dashboard | Data Analyst | power-query, modeling, dax, visuals, testing, communication |
| BI-1057 | Finance disputes the dashboard | Data Analyst | dax, modeling, testing, communication, power-query |
| REQ-301 | Four requests, zero requirements | Data Analyst | communication, modeling, governance |
| UAT-017 | "The Region total doesn't match Excel" | Data Analyst | testing, modeling, communication |
| INC-2031 | A regional manager can see other regions' payroll | BI Developer | security, modeling, testing, governance, communication |
| BI-1103 | Three models, three Revenues | BI Developer | modeling, governance, dax, service, communication, architecture |
| GOV-044 | Usage dropped 70%. Retire it? | BI Developer | governance, service, communication |
| CR-118 | Four change requests to a working model | BI Developer | modeling, dax, security, testing, communication |
| INC-2044 | The executive dashboard takes 18 seconds | Senior BI Developer | performance, dax, modeling, testing, communication |
| INC-2071 | The board pack refresh failed at 06:17 | Senior BI Developer | service, power-query, communication, governance, testing |
| INC-2079 | Hotfix, rollback or wait? | Senior BI Developer | deployment, testing, communication, architecture |
| COMM-12 | Explain it twice | Senior BI Developer | communication, performance |
| PR-214 | Two developers, one measure | BI Engineer | deployment, testing, dax, communication |
| INC-2058 | Test is right, Production is wrong | BI Engineer | deployment, service, testing, automation |
| PR-231 | Review Sam's pull request | BI Engineer | deployment, modeling, dax, performance, communication |
| ARCH-009 | Should Northwind move to Fabric, and how? | BI Architect / Lead | architecture, fabric, performance, governance, communication |
| ARCH-012 | Architecture review: 80 reports, 19 models, no owner | BI Architect / Lead | architecture, governance, security, communication, service |
| GOV-050 | Governance maturity assessment | BI Architect / Lead | governance, architecture, security |