datarekha
SQL Medium Asked at GoogleAsked at AmazonAsked at MetaAsked at Microsoft

What is the logical processing order of a SQL SELECT statement?

The short answer

SQL processes clauses in this order: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT. This matters because it explains why you cannot use a SELECT alias in a WHERE clause, but you can use it in ORDER BY.

How to think about it

The order you write SQL differs from the order the engine evaluates it. This one mental model resolves almost every “why doesn’t this work?” SQL question — alias scoping, WHERE vs HAVING, the ORDER BY exception, all of it. The logical processing order:

FROM          identify tables, apply JOINs

WHERE         filter individual rows (no aggregates, no SELECT aliases)

GROUP BY      collapse rows into groups

HAVING        filter groups (aggregates allowed here)

SELECT        compute expressions, assign aliases

ORDER BY      sort (SELECT aliases now visible)

LIMIT/OFFSET  truncate the sorted result

Two consequences fall straight out. A SELECT alias can’t be used in WHERE (step 2 runs before the alias is computed at step 5) but can be used in ORDER BY (step 6, after). And an aggregate works in HAVING (step 4, after grouping) but not in WHERE (step 2, before any groups exist).

A worked example — WHERE thins, then HAVING judges

Watch WHERE filter rows before grouping and HAVING filter groups after:

SELECT customer_id, COUNT(*) AS order_count, SUM(amount) AS total
FROM orders
WHERE year = 2024            -- step 2: per-row, drops the 2023 order first
GROUP BY customer_id         -- step 3: collapse to one row per customer
HAVING COUNT(*) > 2;         -- step 4: per-group, keep only busy customers
customer_idorder_counttotal
33205

Only customer 3 survives. Trace the pipeline: WHERE year = 2024 removes customer 1’s lone 2023 order before grouping, leaving customer 1 with two 2024 orders, customer 2 with one, and customer 3 with three. After GROUP BY, HAVING COUNT(*) > 2 keeps only customer 3. Try to move COUNT(*) > 2 into WHERE and it errors — at step 2 there’s no count yet to compare.

Learn it properly SELECT basics

Keep practising

All SQL questions

Explore further

Skip to content