← All courses

🧮 Learn SQL

You type every query yourself, against a real business database — from your first SELECT to window functions, CTEs and query tuning. Every lesson ships with runnable koans.

Short on time? The 25 episodes marked core are the shortest path to being productive at work. Start there and pick up the rest whenever a job asks for them.


Series 1 · SQL Fundamentals

SELECT, WHERE, GROUP BY and your first JOIN

  1. 01

    Start Here: The SQL Thinking Loop — Your First Query, CloudBeaver & the Koans

    The fastest way to learn SQL is to write it. You answer a real business question in your first few minutes, learn the loop you'll use every time, and meet the tools you'll practise with: Northwind on PostgreSQL, CloudBeaver, DuckDB and the koans.


    corebeginner#sql#fundamentals#getting-started
  2. 02

    SELECT & Column Lists — Fetching a Table's Data

    Open a database you have never seen and find out what is in it. Ask a table for everything, then ask it for exactly the columns you want, and read what the database says each column is made of.

    corebeginner#sql#fundamentals#select
  3. 03

    Data Types — What a Column Can Hold, and Why Results Surprise You

    Every column has a type, and whoever built the table chose it. Learn to ask any database what it is holding, meet the five families you will actually use, and see why a comparison can hand you an answer that looks right and is not.

    corebeginner#sql#fundamentals#data-types
  4. 04

    WHERE, AND/OR/NOT, IN, BETWEEN — Keeping Only the Rows You Need

    Ask a question and get back only the rows that answer it. One test with =, combined tests with AND and OR (and the parentheses trap between them), lists with IN, ranges with BETWEEN, and the date habit that never miscounts a month.

    corebeginner#sql#fundamentals#where#filtering
  5. 05

    ORDER BY, LIMIT & FETCH FIRST — Sorting Rows and Keeping the Top Few

    Every request that says top, latest, biggest or worst is a sort and a cut. Learn to put rows in the order you want, keep only the few you need, and see why the same query can hand two people different answers.

    corebeginner#sql#fundamentals#order-by#limit
  6. 06

    Aliases, Expressions & DISTINCT — Make Messy Output Look Like a Report

    A correct query is only half the job. Name your columns, build the ones the table hasn't got, round money back into money — and learn why a DISTINCT list stops being distinct the moment you add a column to it.

    corebeginner#sql#fundamentals#alias#distinct#expressions
  7. 07

    Aggregate Functions: COUNT, SUM, AVG, MIN, MAX — Turning Many Rows Into One Number

    How many, how much, the biggest, the smallest, the average. Learn the five functions that collapse a table into a single number — and the two invisible things that decide which rows that number is actually about.

    corebeginner#sql#fundamentals#aggregate-functions#count
  8. 08

    GROUP BY — One Number per Customer, per Month, per Anything

    An aggregate gives you one number for a whole table, and nobody ever asks for that. Learn to get one number per group — and why the columns you group by decide what one row of your report actually means.

    corebeginner#sql#fundamentals#group-by#aggregates
  9. 09

    HAVING vs WHERE — Filtering Groups and Filtering Rows

    You can build a total. Now keep only the groups you want. Learn what HAVING does, the order a database really runs your query in, and why putting a filter one clause too early gives you a wrong answer that proves itself right.

    corebeginner#sql#fundamentals#having#group-by
  10. 10

    JOINs: INNER, LEFT, RIGHT, FULL — Combining Rows From Two Tables

    The data you need is almost never in one table. Learn to match rows across two tables with JOIN and ON, keep the rows that match nothing, and see why moving one condition from ON into WHERE silently undoes a LEFT JOIN.

    corebeginner#sql#fundamentals#joins#left-join
  11. 11

    NULL & Three-Valued Logic — How Missing Values Change Your Results

    An empty cell is not a value, so comparing it to one answers neither yes nor no. Learn why = NULL matches nothing, why a filter and its opposite do not add up, and the two places a missing value quietly changes a number you were about to send someone.

    corebeginner#sql#fundamentals#null#three-valued-logic#coalesce
  12. 12

    SELECT + JOIN + GROUP BY — Building Your First Real Report

    Build a top 10 customers report with SELECT, JOIN, GROUP BY, SUM, ORDER BY and LIMIT, and learn the two checks that show whether its numbers are right before anybody acts on them.

    corebeginner#sql#fundamentals#join#group-by#reporting#project

Series 2 · Intermediate SQL

CTEs, subqueries and window functions on real questions

  1. 01

    Subqueries — Using One Query's Result Inside Another

    Put a query in brackets inside another query: compare with the value it returns, test a list with IN, or query the table it builds, and check which average you are really comparing with.


    coreintermediate#sql#intermediate#subqueries#in#having#grain
  2. 02

    CASE — SQL's If/Then for Labels & Buckets

    coreintermediatecoming soon
  3. 03

    Dates & Times — Getting Ranges and Boundaries Right

    coreintermediatecoming soon
  4. 04

    Multi-Table JOINs & Grain — When a Join Silently Drops or Multiplies Your Rows

    coreintermediatecoming soon
  5. 05

    CTEs (WITH) — Breaking a Long Query Into Named Steps

    coreintermediatecoming soon
  6. 06

    VIEWs, CREATE TABLE AS & Temp Tables — Save the Query, or Save Its Answer

    intermediatecoming soon
  7. 07

    EXISTS & Correlated Subqueries — Questions About Each Row, and the NOT IN Trap

    coreintermediatecoming soon
  8. 08

    Self-JOINs & Hierarchies — Relating Rows to Other Rows in the Same Table

    intermediatecoming soon
  9. 09

    Window Functions I: OVER, PARTITION BY & ROW_NUMBER — The Latest Row per Customer

    coreintermediatecoming soon
  10. 10

    String Functions, LIKE & Regex — Clean Up Messy Real-World Data

    coreintermediatecoming soon
  11. 11

    Window Functions II: LAG/LEAD, Running Totals & Frames — Month-over-Month Growth in One Query

    coreintermediatecoming soon
  12. 12

    UNION, INTERSECT, EXCEPT — Stacking and Reconciling Result Sets

    coreintermediatecoming soon
  13. 13

    GROUPING SETS, ROLLUP & CUBE — Subtotals and Grand Totals in One Pass

    intermediatecoming soon
  14. 14

    INSERT, UPDATE, DELETE & Transactions — Change the Data, Safely

    coreintermediatecoming soon
  15. 15

    UPSERT & MERGE — Insert or Update in One Statement, and Loads You Can Run Twice

    coreintermediatecoming soon
  16. 16

    Median and Percentiles — WITHIN GROUP, and Why AVG Is Not the Answer

    intermediatecoming soon
  17. 17

    Subqueries + CTEs + Window Functions — Solving a Real Business Case, End to End

    coreintermediate#projectcoming soon
  18. 18

    Subqueries (v2 pilot) — Using One Query's Result Inside Another

    Put a query in brackets inside another query: compare with the value it returns, test a list with IN, or query the table it builds, and check which average you are really comparing with.

    intermediate#sql#intermediate#subqueries#in#having#grain

Series 3 · Advanced SQL

the harder queries, and how to make a slow one fast

  1. 01

    PIVOT & UNPIVOT — Turn Rows into a Cross-Tab Report, the Portable Way

    advancedcoming soon
  2. 02

    JSON in SQL — Query Semi-Structured Data Without Leaving the Database

    advancedcoming soon
  3. 03

    Recursive CTEs — Walk an Org Chart to the Top

    advancedcoming soon
  4. 04

    Gaps & Islands — Find Streaks, Runs and Missing Periods

    advancedcoming soon
  5. 05

    Cohorts & Repeat-Purchase Analysis — Measuring Who Comes Back, and When

    advancedcoming soon
  6. 06

    Writing a Query That Can Be Fast — Filter Early, Don't Hide the Column

    advancedcoming soon
  7. 07

    EXPLAIN / EXPLAIN ANALYZE — Reading the Plan to Find Out Why a Query Is Slow

    advancedcoming soon
  8. 08

    Rewrites That Change the Plan — EXISTS, DISTINCT and Deep Pagination

    advancedcoming soon
  9. 09

    Indexes — Making a Query Faster, and What an Index Costs

    advancedcoming soon
  10. 10

    COUNT(DISTINCT) — the Aggregate That Will Not Decompose

    advancedcoming soon
  11. 11

    Query Tuning — Making a Real Slow Query Fast

    advanced#projectcoming soon

Series 4 · Cross-Vendor SQL

one query, five databases

  1. 01

    ANSI SQL vs Dialects — Why SQL That Works Here Fails on Another Database

    advancedcoming soon
  2. 02

    Portable Paging, Strings, Dates & UPSERT — One Query That Runs on Every Engine

    advancedcoming soon
  3. 03

    Northwind on Postgres, Oracle, SQL Server, MySQL & Db2 — One Query, Five Databases

    advanced#projectcoming soon

Where this leads


Not here, on purpose

  • DDL, keys, constraints & normalization — covered in Learn Data Modeling — it's schema design, not writing queries
  • Whether a column should be nullable at all — covered in Data Modeling, Series 1, which is the design decision. In this course, Series 1 · 45 is what NULL does to a query
  • Deciding to store JSON in the first place — covered in Data Modeling, Series 2. In this course, Series 3 queries JSON once that decision has been made
  • Choosing indexes while designing the schema — covered in Data Modeling, Series 2. In this course, Series 3 is EXPLAIN and the mechanics, on a query that already exists
  • Isolation levels, locking & concurrency — covered in Data Ops, Series 2 — Running PostgreSQL in Production. In this course, Series 2 · 55 covers the COMMIT and ROLLBACK basics
  • Stored procedures, functions and triggers — covered in each engine's own course, because the procedural languages share almost no syntax — PostgreSQL, SQL Server, Oracle Database, and MySQL & MariaDB. In this course, SQL is what you send, not what runs inside the server
  • OLAP cubes and the warehouse use of ROLLUP / CUBE — covered in Data Warehousing: Series 1 uses them over a star schema and Series 2 builds OLAP cubes. In this course, Series 2 · 50 is the SQL itself (GROUPING SETS, ROLLUP, CUBE, GROUPING())
  • Exporting query results to a file (COPY, \copy, client export) — covered in ETL & Data Pipelines, Series 1, where a file is a sink you write to and the permissions and row-count checks come with it. In this course a result set is something you read, not a file you produce