Databases 6 min read

What’s the Real Execution Order of SQL Queries? A Visual Guide

Although most SQL statements begin with SELECT, the actual execution follows a specific order—WHERE, GROUP BY, HAVING, then SELECT—illustrated by a diagram that also clarifies common misconceptions about filtering window functions, column aliases, and how databases may reorder operations for optimization.

Java Backend Technology
Java Backend Technology
Java Backend Technology
What’s the Real Execution Order of SQL Queries? A Visual Guide

SQL Query Execution Order

Many SQL queries start with SELECT, but the engine processes clauses in a different sequence. The execution order is roughly: FROM → JOIN → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT, with SELECT being the fifth step.

This diagram answers the following questions

Can WHERE be used after GROUP BY? (No, WHERE is evaluated before GROUP BY.)

Can you filter the results of a window function? (No, window functions are evaluated in SELECT after WHERE and GROUP BY.)

Can ORDER BY be based on GROUP BY expressions? (Yes, ORDER BY is executed last and can reference any prior expression.)

When is LIMIT applied? (At the very end of execution.)

Database engines often reorder these steps for performance, which will be discussed in later articles.

Mixed Factors: Column Aliases

Some SQL implementations allow using column aliases in GROUP BY, giving the impression that GROUP BY runs after SELECT. In reality, the engine rewrites the query so that GROUP BY still executes first.

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*) FROM table GROUP BY full_name

The engine may transform it to:

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*) FROM table GROUP BY CONCAT(first_name, ' ', last_name)

Thus GROUP BY remains the earlier operation.

Database May Not Follow This Order (Optimization)

In practice, engines can reorder JOIN, WHERE, GROUP BY, etc., to achieve faster execution without altering the result set.

Example:

SELECT * FROM owners LEFT JOIN cats ON owners.id = cats.owner WHERE cats.name = 'mr darcy'

Filtering before the join reduces the amount of data processed, improving performance.

LINQ Queries Start with FROM

LINQ (C# and VB.NET) follows a FROM → WHERE → SELECT order. Example:

var teenAgerStudent = from s in studentList where s.Age > 12 && s.Age < 20 select s;

Pandas queries follow a similar logical flow, though the code order is flexible:

df = thing1.join(thing2)  # JOIN
df = df[df.created_at > 1000]  # WHERE
df = df.groupby('something', num_yes=('yes','sum'))  # GROUP BY
df = df[df.num_yes > 2]  # HAVING
df = df[['num_yes','something1','something']]  # SELECT
df.sort_values('sometthing', ascending=True)[:30]  # ORDER BY and LIMIT
df[:30]
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

optimizationSQLdatabaseQuery ExecutionpandasWindow FunctionsLINQ
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

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.