A course for getting out of the state where you patch copy-pasted SQL until it works. SELECT and WHERE, NULL and three-valued logic, the difference between JOIN and LEFT JOIN, window functions, transactions and locks, normalisation, indexes and EXPLAIN. Thirty lessons that take you to explaining why a query returns what it returns.
The 30 lessons are grouped into six chapters. Working through them in order is the best way, but you are welcome to read only the part you are stuck on right now. Note: SQL cannot run inside the browser. Install MySQL 8.4 (or 8.0), load the sample data from lesson 1, and try it there.
Connecting, creating a database and tables, and putting rows in and getting them back. The sample data you build here stays with you until lesson 30.
Choosing columns and aliasing them, WHERE conditions, LIKE patterns, and NULL. You go down to three-valued logic to see why "= NULL" never matches, then finish with ordering and pagination.
From the fact that COUNT skips NULL through GROUP BY and HAVING, and then into JOIN. INNER against LEFT, what happens when ON and WHERE get mixed up, self joins, subqueries and CTEs.
Writing "rank within each group" in a single statement with window functions, walking into the traps around dates and times, INSERT in practice, and running UPDATE and DELETE safely.
Transactions and locks, and how to read a deadlock. Then choosing data types, primary and foreign keys, and normalisation — the decisions that are hardest to change later.
When an index helps and when it cannot, how to read EXPLAIN, character sets and collations, privileges and backups, and connecting from an application. It ends by running design through to implementation.
Once you have finished all 30 lessons, see the same material through PostgreSQL in Database Fundamentals with PostgreSQL. To drive it from an application, continue with Django or FastAPI. Membership unlocks every course.