Understanding SQL Order of Execution and Key Clauses

Simran Sandhu
3 min readJul 2, 2024

--

Structured Query Language (SQL) is a powerful tool used for managing and manipulating relational databases. Understanding the order in which SQL executes various clauses is crucial for writing efficient and effective queries. Let’s break down the order of execution and the significance of each key clause in SQL.

1. FROM / JOIN

**Execution Order:** First

The `FROM` clause is the starting point of any SQL query. It specifies the table from which data is to be retrieved. When dealing with multiple tables, the `JOIN` clause comes into play to combine rows from these tables based on a related column.

**Importance:**
- Defines the data source.
- Sets the stage for the rest of the query.
- Joins allow for combining data from multiple tables, which is essential for complex queries.


SELECT *
FROM employees
JOIN departments ON employees.department_id = departments.id;

2. WHERE

**Execution Order:** Second

The `WHERE` clause filters records based on specified conditions. It eliminates rows that do not meet the criteria, ensuring that only relevant data is processed in subsequent steps.

**Importance:**
- Reduces the number of rows for processing, enhancing performance.
- Ensures that only pertinent data is considered for further operations.


SELECT *
FROM employees
WHERE salary > 50000;

3. GROUP BY

**Execution Order:** Third

The `GROUP BY` clause groups rows that have the same values in specified columns into summary rows. It is commonly used with aggregate functions (e.g., COUNT, MAX, MIN, SUM, AVG).

*Importance:**
- Aggregates data for meaningful insights.
- Facilitates data analysis by grouping similar items.


SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id;

4. HAVING

**Execution Order:** Fourth

The `HAVING` clause is similar to `WHERE` but is used for filtering groups created by the `GROUP BY` clause. It allows conditions to be applied to aggregated data.

*Importance:**
- Provides an additional layer of filtering for aggregated data.
- Ensures that only groups meeting certain conditions are included in the results.


SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 10;

5. SELECT

**Execution Order:** Fifth

The `SELECT` clause specifies the columns to be included in the result set. It determines the final output of the query.

**Importance:**
- Defines the data to be retrieved.
- Can include calculations, expressions, and aliases.


SELECT employee_id, first_name, last_name
FROM employees;

6. DISTINCT

**Execution Order:** Sixth (applied within the `SELECT` clause)

The `DISTINCT` keyword ensures that the results contain only unique values, eliminating duplicate rows from the result set.

*Importance:**
- Removes duplicates.
- Provides a unique set of results.


SELECT DISTINCT department_id
FROM employees;

7. ORDER BY

**Execution Order:** Seventh

The `ORDER BY` clause sorts the result set by one or more columns. It can sort data in ascending (default) or descending order.

**Importance:**
- Organizes data in a specified order.
- Enhances readability and usability of the results.


SELECT first_name, last_name, salary
FROM employees
ORDER BY salary DESC;

8. LIMIT / OFFSET

**Execution Order:** Eighth

The `LIMIT` clause restricts the number of rows returned by the query. The `OFFSET` clause skips a specified number of rows before starting to return rows.

**Importance:**
- Controls the volume of data retrieved.
- Useful for pagination and managing large datasets.


SELECT first_name, last_name
FROM employees
ORDER BY last_name
LIMIT 10 OFFSET 20;

Example:


SELECT DISTINCT
employees.department_id,
departments.department_name,
COUNT(employees.employee_id) AS employee_count,
AVG(employees.salary) AS average_salary
FROM
employees
JOIN
departments ON employees.department_id = departments.id
WHERE
employees.salary > 50000
GROUP BY
employees.department_id, departments.department_name
HAVING
COUNT(employees.employee_id) > 5
ORDER BY
average_salary DESC
LIMIT 10 OFFSET 5;

Explanation

1. **FROM / JOIN**:
- `FROM employees`: Starts by specifying the `employees` table.
- `JOIN departments ON employees.department_id = departments.id`: Joins the `departments` table to include department names.
2. **WHERE**:
- `WHERE employees.salary > 50000`: Filters employees with a salary greater than 50,000.
3. **GROUP BY**:
- `GROUP BY employees.department_id, departments.department_name`: Groups the results by department ID and name.
4. **HAVING**:
- `HAVING COUNT(employees.employee_id) > 5`: Filters groups to include only those with more than five employees.
5. **SELECT**:
- `SELECT DISTINCT employees.department_id, departments.department_name, COUNT(employees.employee_id) AS employee_count, AVG(employees.salary) AS average_salary`: Selects distinct department IDs, department names, the count of employees, and the average salary.
6. **DISTINCT**:
- `SELECT DISTINCT`: Ensures that each row in the result set is unique.
7. **ORDER BY**:
- `ORDER BY average_salary DESC`: Sorts the result set by average salary in descending order.
8. **LIMIT / OFFSET**:
- `LIMIT 10 OFFSET 5`: Limits the result set to 10 rows, starting from the 6th row (offset by 5).

This query effectively demonstrates the proper sequence of SQL execution and the purpose of each clause in a single, comprehensive query.

Conclusion

Understanding the order of execution and the role of each clause in SQL is essential for writing efficient queries. By following this order, you can effectively manipulate and retrieve the data you need from relational databases.

--

--

Simran Sandhu
Simran Sandhu

Written by Simran Sandhu

Passionate Engineer, Mother. "Without continual growth and progress, such words as improvement, achievement, and success have no meaning." - Benjamin Franklin

No responses yet