SQL VISUALIZER

SQL Execution Order: How a Query Really Runs

You write SELECT first, but the database runs it almost last. A SQL query is processed in a fixed logical order that explains a lot of otherwise-confusing behaviour — like why you can filter on a column alias in ORDER BY but not in WHERE.

▶ Open the full-pipeline example in SQL Visualizer

The logical order of operations

Whatever order you type the keywords, the engine resolves them in this sequence:

  1. FROM — choose the source table(s)
  2. JOIN — combine rows from other tables
  3. WHERE — filter individual rows
  4. GROUP BY — collapse rows into groups
  5. HAVING — filter the groups
  6. SELECT — pick / compute the output columns (aliases are born here)
  7. ORDER BY — sort the result
  8. LIMIT — keep the first N rows

A query that uses every stage

This query touches all eight stages. Open it in the visualizer to watch each clause transform the rows in turn:

SELECT d.name AS director, m.genre,
       SUM(m.revenue) AS total_revenue, COUNT(*) AS films
FROM movies m
INNER JOIN directors d ON m.director_id = d.director_id
WHERE m.year >= 2000 AND m.budget > 20
GROUP BY d.name, m.genre
HAVING SUM(m.revenue) > 200
ORDER BY total_revenue DESC
LIMIT 8
FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

1–2. FROM and JOIN: assemble the rows

First the engine reads movies, then matches each movie to its director. See SQL JOINs explained for how matching actually works.

3. WHERE: filter rows

Rows that fail the predicate (here, films before 2000 or with a budget ≤ 20) are dropped before any grouping happens. WHERE sees raw row values, never aggregates.

4–5. GROUP BY and HAVING: groups, then group filters

Surviving rows collapse into one row per (director, genre) pair, and aggregates like SUM and COUNT are computed per group. HAVING then filters those groups — see WHERE vs HAVING and GROUP BY and HAVING.

6–8. SELECT, ORDER BY, LIMIT

SELECT computes the output columns and names them (total_revenue is created here). ORDER BY can use that alias because it runs later; LIMIT finally trims to the top 8 rows.

Why the order matters in practice

▶ Open the full-pipeline example in SQL Visualizer