Real SQLite in your browser, on Meridian's sales data. Exercises follow the six chapters: warm-ups first, then CTEs, window functions, data-quality audits, and reconciliation. Explore freely, e.g. SELECT * FROM deals LIMIT 5;

Tables and columns (as of 31 Aug 2026)
  • accounts · Customer companies

    account_id, account_name, industry, region, tier, created_date

  • customers · Contacts at accounts

    customer_id, account_id, full_name, role, email

  • deals · One row per opportunity; stage is the current CRM value

    deal_id, account_id, owner, stage, amount, source, created_date, closed_date

  • deal_stage_history · Append-only log of stage transitions

    history_id, deal_id, stage, entered_at

  • transactions · Money movements against closed_won deals

    transaction_id, deal_id, amount, transaction_date, type

  • pipeline_runs · Daily run log for 3 pipelines (Apr–Aug 2026)

    run_id, pipeline, run_date, started_at, finished_at, status, rows_in, rows_out

  • dashboard_views · Usage events for the legacy and new dashboards

    view_id, dashboard, viewer_id, viewer_role, viewed_at

Level 0 · The basics · SQL & Python 101

Pick columns, keep rows

Warm-up

Return the deal_id, owner, and amount of every deal currently in stage qualified, ordered by deal_id.

Why this matters for a data product

SELECT / FROM / WHERE / ORDER BY is the sentence every other query extends. Being able to list the exact rows behind a number is the first habit of a Data PM.

Related: SQL 101: the formulas