Skip to the solution
EasyDSA12 min read

What is the logical order of execution of a SQL query?

1.1k views

The problem

Question presented to candidate: "We write a query starting with SELECT, but the database does not run it top to bottom. Walk me through the order in which the clauses are logically evaluated, and use it to explain why you can use a column alias in ORDER BY but not in WHERE."

What a strong answer should cover:

  • The logical order: FROM and JOINs, then WHERE, GROUP BY, HAVING, window functions, SELECT, DISTINCT, ORDER BY, and finally LIMIT / OFFSET
  • Consequences: WHERE cannot see aggregates or SELECT aliases, HAVING filters groups, window functions cannot be filtered in the same query level, ORDER BY can use aliases
  • The difference between this logical order (what the query means) and the physical plan (what the engine actually does, such as pushing a filter into a scan)
  • Engine differences: SQLite and MySQL accept some aliases where the standard and PostgreSQL do not
  • The fix when you need a later value earlier: wrap the query in a subquery or CTE

Code / implementation expected: Optional โ€” explain with one grouped query, ideally showing the alias error and the subquery fix.

Schema used by the examples:

  • order-of-execution

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

12 min read ยท 9 sections

Run the code

Edit the query and run it against the tables for this question.

SQLPeel one query apart: the rows that survive each step
SQLWindow functions run after WHERE: rank inside a filter, then filter on the rank in an outer query
SQLSQLite accepts a SELECT alias in WHERE and HAVING (PostgreSQL rejects both)
PostgreSQL: the physical plan pushes WHERE into the table scan
EXPLAIN (COSTS OFF)
SELECT d.name AS dept, COUNT(*) AS headcount
FROM employees AS e
JOIN departments AS d ON d.id = e.dept_id
WHERE e.hired >= '2019-01-01'
GROUP BY d.name
HAVING COUNT(*) >= 2
ORDER BY headcount DESC
LIMIT 2;

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 3 of 82 in SQL

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All SQL questions
Up nextEasy

What is the CASE expression?

Continue