booting sqlite (wasm)…

SQL Explainer

— watch a real SQLite engine run your query, clause by clause
ready
evaluating / kept
filtered out
group
click a stage to zoom in ↗
speed

What's actually happening when a query runs

Write a query with SELECT at the top and WHERE in the middle — but that's not the order SQLite actually executes it in. The engine works through clauses in a fixed logical sequence, rebuilding and shrinking the row set at every step. The diagram above runs your exact query through sql.js — real SQLite compiled to WebAssembly — and shows the true intermediate result after each stage. Click any stage to zoom in and see its exact underlying SQL and full row grid.

Every colored cell above is a real value from the database — column values are shaded by magnitude (numbers) or category (text) so you can see patterns in the data at a glance, the way a spreadsheet heatmap works. Nothing here is a hand-authored animation.

FROM & JOIN

Execution starts here, not at SELECT. The engine loads the base table(s) and, if a JOIN is present, matches rows between tables on the join condition before anything else happens.

WHERE

Every row from FROM/JOIN is tested against the condition. Rows that evaluate true continue forward; rows that evaluate false are discarded permanently for the rest of this query — you can see them peel off into the faded strip below each WHERE stage.

GROUP BY

Surviving rows are bucketed into groups sharing the same value(s) in the GROUP BY column(s). From here on, only grouped columns or aggregates like COUNT(), SUM(), AVG() can appear in SELECT.

HAVING

HAVING filters entire groups, often by an aggregate condition (e.g. HAVING COUNT(*) > 3) — which is why aggregates can't be used in WHERE: groups don't exist yet at that point.

SELECT & DISTINCT

Only now does the engine project down to the columns/expressions you asked for. DISTINCT, if present, collapses duplicate resulting rows at this same stage.

ORDER BY

With the final row shape decided, the engine sorts the result — which is why you can ORDER BY a column alias defined moments earlier in SELECT.

LIMIT / OFFSET

Finally, the sorted result is trimmed to the requested window — always the very last step, always applied to the fully filtered, grouped, and sorted output.

Built with real client-side SQL execution via sql.js (SQLite → WebAssembly). No server, no scripted data.