What is the logical order of execution of a SQL SELECT query?
Quick Answer
Even though you write SELECT first, SQL Server logically processes: FROM / JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → TOP / OFFSET-FETCH. This is why a column alias defined in SELECT can't be used in WHERE or GROUP BY, but can be used in ORDER BY.
You write SELECT at the top, but the engine processes FROM and the joins first, then WHERE, then GROUP BY, then HAVING, then SELECT, then ORDER BY, then TOP. That order explains a lot of the questions people have — why you can't use a column alias from the SELECT list in the WHERE clause, because WHERE runs before SELECT, but you can use it in ORDER BY. And it's why you can't filter on a window function in WHERE — window functions run at the SELECT stage.
Consequences of this order:
WHEREcan't reference aSELECTalias or an aggregate (both come later) — use the full expression or a CTE.ORDER BYcan use aSELECTalias because it runs afterSELECT.- Window functions run during
SELECT, so you can't filter on them inWHERE— wrap in a CTE. - The optimiser may physically execute things differently, but the result must match this logical order.