Databases 6 min read

Understanding SQL Query Execution Order: FROM, JOIN, WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, and LIMIT

The article explains the true execution order of SQL queries, detailing each step from FROM and JOIN through WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, and LIMIT, and illustrates the concepts with examples and code snippets.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding SQL Query Execution Order: FROM, JOIN, WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, and LIMIT

Standard query statement (illustrated in the original article).

The actual SQL execution order is:

Execute FROM and JOIN to determine table relationships and produce an initial dataset.

Apply WHERE for basic row filtering.

Perform GROUP BY to group rows.

Apply HAVING for group‑level filtering, which can include aggregate functions.

Execute SELECT to retrieve columns or aggregate results; aggregate functions add new fields.

Apply DISTINCT to remove duplicate rows.

Finally, ORDER BY sorts the result set according to the specified criteria.

Data Association Process

Two tables are involved in the example.

FROM & JOIN & WHERE

These clauses define the scope of tables to query and how they are related.

Single‑table join example:

from table1 join table2 on table1.id = table2.id

Multi‑table join using WHERE:

from table1, table2 where table1.id = table2.id

Without a join condition, a Cartesian product occurs.

GROUP BY

GROUP BY partitions data according to the specified columns but does not filter rows.

Example: grouping by the parity of an ID.

HAVING & WHERE

HAVING can contain both ordinary conditions and aggregate functions, while WHERE is limited to non‑aggregate conditions. Often HAVING can replace WHERE for a smoother query.

Using WHERE before GROUP BY filters rows first, then groups them.

Using GROUP BY then HAVING filters groups after aggregation; the result is effectively the same for non‑aggregate conditions.

Example illustrating that splitting a constant before division does not change the final result, so WHERE‑then‑GROUP BY and GROUP BY‑then‑HAVING produce identical outcomes for simple filters.

HAVING differs because it supports aggregate functions, allowing conditions such as having salary < avg(salary) to filter out rows whose salary is below the group average.

SELECT

After grouping, SELECT retrieves the desired columns. Aggregate functions generate additional fields. Duplicate column names must be qualified to avoid ambiguity, and DISTINCT can be used to remove duplicate rows, e.g.:

select employee.id, distinct name, salary, avg(salary)

ORDER BY

ORDER BY sorts the final result set, for example by id . If a LIMIT clause is present, the engine stops retrieving rows once the required number of sorted rows is obtained.

LIMIT

LIMIT is applied after ORDER BY. Placing LIMIT before sorting can yield incorrect results because the first N rows may not be the smallest or largest according to the intended order.

For instance, limit 0,3 taken before sorting would return the first three rows regardless of their values, which may not be the three smallest salaries.
SQLDatabasejoinlimitquery executionORDER BYFROMGROUP BYHAVINGWHERE
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.