CHAPTER 29
The secret that explains 80% of SQL errors.
You write SQL in this order: SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
But SQL excute in this order:
| Execution Step | Clause | What happens |
|---|---|---|
| 1 | FROM | Identify the source table(s) |
| 2 | JOIN | Combine joined tables |
| 3 | WHERE | Filter individual rows |
| 4 | GROUP BY | Group remaining rows |
| 5 | HAVING | Filter groups |
| 6 | SELECT | Compute output columns and aliases |
| 7 | DISTINCT | Remove duplicate rows |
| 8 | ORDER BY | Sort the result |
| 9 | LIMIT | Restrict row count |
These FAIL - and now you know why
-- FAILS: WHERE runs before SELECT, alias 'annual' doesn't exist yet SELECT salary * 12 AS annual FROM employees WHERE annual > 100000; -- FAILS: WHERE cannot use aggregate functions SELECT department FROM employees WHERE COUNT(*) > 2; -- FAILS: HAVING is not available without GROUP BY in most dialects SELECT name FROM employees HAVING salary > 70000;
These FAIL - and now you know why
-- Use the expression directly in WHERE SELECT salary * 12 AS annual FROM employees WHERE salary * 12 > 100000; -- Use HAVING for aggregate filters SELECT department FROM employees GROUP BY department HAVING COUNT(*) > 2; -- Alias is fine in ORDER BY (runs after SELECT) SELECT salary * 12 AS annual FROM employees ORDER BY annual DESC;
✅ Interview Tips: Why can't I use a SELECT alias in a WHERE clause?' is a common interview screening question. It filters candidates who have merely memorised syntax from those who understand how SQL actually executes.