How a Query Is Processed
Prerequisites: Filtering groups with HAVING, Limiting results and pagination
You write a query in one order, but the database processes it in a different, logical order. Knowing that order explains many rules and error messages.
Written order vs logical order
SELECT category, COUNT(*) AS products -- 5
FROM products -- 1
WHERE price > 30 -- 2
GROUP BY category -- 3
HAVING COUNT(*) >= 1 -- 4
ORDER BY products DESC, category -- 6
LIMIT 2; -- 7
+-------------+----------+
| category | products |
+-------------+----------+
| Accessories | 3 |
| Audio | 1 |
+-------------+----------+
- FROM — pick the table (and join others, in Level 2).
- WHERE — filter individual rows.
- GROUP BY — form groups.
- HAVING — filter groups.
- SELECT — compute the output columns and aliases.
- ORDER BY — sort the result.
- LIMIT — keep the first rows.
What this explains
- Why
WHEREcan't use aggregates — it runs before groups exist. - Why
WHEREcan't use aSELECTalias — the alias hasn't been created yet at step 2. (SQLite and MySQL allow it as an extension; PostgreSQL and standard SQL don't.) - Why
ORDER BYcan use aliases — it runs afterSELECT. - Why
LIMITneedsORDER BY— without sorting first, "the first 2 rows" isn't well defined.
The database's optimizer may actually execute steps in a different physical order for speed, but the results always match this logical order.