Scrollytelling: SQL, one step at a time
A finished query shows the answer and hides the steps that produced it.
Each diagram here pins a small table in place and changes it as you
scroll, one step per card: rows fade when a clause removes them, groups
take a color, and a NULL shows up as a dark cell. Every one
is built around a question learners ask when a query returns something
they did not expect.
There are 19 diagrams across the 7 Examples pages. Each link below opens its diagram in place, next to the runnable examples that use the same command. Use Copy link to share one.
Selection
From Selection Techniques
-
SELECT chooses columns, never rows
Does SELECT remove rows? What does AS change?
5 steps Open → -
DISTINCT: repeated values collapse to one
What counts as a duplicate, with one column and with two?
5 steps Open → -
COUNT(*), COUNT(column), and COUNT(DISTINCT column)
Why do three COUNTs of the same table give 6, 3, and 2?
5 steps Open →
Filtering
From Filtering Techniques
-
BETWEEN includes both ends, and IN checks a list
Is the boundary value included? What does IN replace?
4 steps Open → -
AND, OR, and what the parentheses change
Why did mixing AND with OR return the wrong rows?
4 steps Open → -
LIKE: what % and _ stand for
Which letters does % cover, and how is _ different?
5 steps Open → -
NULL is not a value: = NULL versus IS NULL
Why does = NULL return nothing, with no error?
5 steps Open →
Aggregating
-
An aggregate turns a whole column into one value
What do SUM, AVG, MIN, and MAX do with a NULL?
5 steps Open →
Sorting and Grouping
From Sorting and Grouping Techniques
-
The order SQL runs the clauses
Why can't WHERE see my SELECT alias?
7 steps Open → -
ORDER BY two columns: sort, then break ties
What does the second ORDER BY column do?
4 steps Open → -
GROUP BY: many rows collapse to one per group
How do many rows become one row per group? WHERE or HAVING?
4 steps Open →
Transforming
-
CASE WHEN: the first test that passes wins
Why is every row labeled with the first category?
5 steps Open → -
A computed column, and why the query says 100.0
Why is my percentage column all zeros?
4 steps Open →
Joining
From Joining Techniques
-
INNER JOIN: keep only matched rows
Which rows survive an INNER JOIN?
7 steps Open → -
LEFT JOIN: keep every left row
Where do the NULLs in a LEFT JOIN come from?
5 steps Open → -
One row, many matches: the join multiplies
Why did my row count go up after a join?
5 steps Open → -
Anti-join: keep only the left rows with no match
How do I find the rows with no match?
4 steps Open →
Going Further
From Going Further
-
A subquery runs first, then the outer query uses its answer
How do I get the row that holds the minimum, not only the number?
5 steps Open → -
Counting after a LEFT JOIN: COUNT(*) versus COUNT(t.town)
Why does a county with no towns show a count of 1?
4 steps Open →