Transforming subqueries into joins

Key takeaways:

  • Transforming subqueries into joins enhances SQL query performance and clarity.

  • Subqueries allow for querying within queries.

  • Joins connect tables based on related columns, often leading to more efficient queries.

  • Using joins can improve readability, maintainability, and speed of database operations compared to subqueries.

Transforming subqueries into joins refers to the process of converting SQL subqueries into join operations. This can make your queries faster and easier to understand. Optimizing SQL queries is important for improving database performance.

Overview of subqueries and joins

Let’s have an overview of subqueries and joins.

Subquery

A subquery is a feature in an SQL database that allows writing a query within a query. In a subquery, the outer query, also called the parent query, filters the data based on results from another query. A subquery is also known as a nested query or inner query. It is useful when performing operations based on related data between one or more tables.

Visualization of a subquery
Visualization of a subquery

MySQL provides us with the following types of subqueries:

  • Single-row subquery

  • Multiple-row subquery

  • Correlated subquery

  • Scalar subquery

  • Single-column subquery

  • Multiple-column subquery

  • Nested subquery

They can be useful but sometimes slow down performance.

Join

A join operation connects one or more tables based on a similar column/attribute between them. Joins connect tables based on related columns and are often more efficient and straightforward than subqueries. If a table connects to itself using joins for some calculation, it is called a self join. MySQL provides us with the following types of joins:

Transforming subqueries into joins

Let’s set up the tables before having a look at the query. Let’s create three tables to demonstrate the concept properly:

-- Create the Employees table
CREATE TABLE Employees (
EmpID INT AUTO_INCREMENT PRIMARY KEY,
EmpName VARCHAR(100),
Salary DECIMAL(10, 2));
-- Insert sample data into Employees table
INSERT INTO Employees (EmpID, EmpName, Salary) VALUES
(1, 'Susan Lee', 50000),
(2, 'Alexa Smith', 60000),
(3, 'Sana Amberson', 45000),
(4, 'Sarah Ronald', 47000);
-- Create the Skills table
CREATE TABLE Skills (
SkillID INT AUTO_INCREMENT PRIMARY Key,
EmpID INT,
SkillName VARCHAR(100),
FOREIGN KEY (EmpID) REFERENCES Employees (EmpID));
-- Insert sample data into Skills table
INSERT INTO Skills (SkillID, EmpID, SkillName) VALUES
(1, 1, 'C++'),
(2, 4, 'Java'),
(3, 1, 'Python'),
(4, 3, 'Blender'),
(5, NULL, 'Android');
-- Create the Projects table
CREATE TABLE Projects (
ProjectID INT AUTO_INCREMENT PRIMARY Key,
EmpID INT,
SkillID INT,
ProjectName VARCHAR(100),
FOREIGN KEY (EmpID) REFERENCES Employees (EmpID),
FOREIGN Key (SkillID) REFERENCES Skills (SkillID));
-- Insert sample data into Projects table
INSERT INTO Projects (ProjectID, EmpID, SkillID, ProjectName) VALUES
(1, 1, 1, 'Industrial Robot'),
(2, 4, 2, 'Multiplatform GUI'),
(3, 3, 4, '3D Simulation'),
(4, 1, 3, 'Deep Learning Model'),
(5, NULL, NULL, 'IOS App'),
(6, 1, NULL, 'Advanced Calculator'),
(7, NULL, 5, 'Android App');

Code explanation

The explanation of the above code is given below:

  • Lines 2–5: We have created a table, Employees. The Employees table has columns EmpIDEmpName, and Salary.

  • Lines 8–12: We insert sample data in the Employees table.

  • Lines 15–19: We have created a table, Skills. The Skills table has columns SkillIDEmpID, SkillName, and a foreign key reference to EmpID in the Employees table.

  • Lines 22–27: We insert sample data in the Skills table.

  • Lines 30–36: We have created a table, Projects. The Projects table has columns ProjectIDEmpIDSkillID, ProjectName, and foreign key references to EmpID in the Employees table and SkillID in the Skills table.

  • Lines 39–46: We insert sample data in the Projects table.

Example 1: Identifying employees involved in projects without listed skills

Let’s find employees who are involved in projects but do not have skills listed in the Skills table. Have a look at the following query:

SELECT e.EmpName
FROM Employees e
WHERE e.EmpID IN (
SELECT p.EmpID
FROM Projects p
WHERE p.SkillID IS NULL);

Code explanation

The explanation of the query is given below:

  • Lines 1–3: We retrieve the employee names from the Employees table, aliased as e, and filter the results to include only those employees whose IDs are found in the results of the subquery.

  • Lines 4–6: The subquery selects employee IDs from the Projects table, aliased as p, where the SkillID is NULL.

We will now transform the previous subquery into a join. In this example, we’ll use an INNER JOIN to achieve the same result. The join method can sometimes provide better performance and readability. Here’s the equivalent query using a join:

SELECT e.EmpName
FROM Employees e
INNER JOIN Projects p
ON e.EmpID = p.EmpID
WHERE p.SkillID IS NULL
GROUP BY e.EmpID, e.EmpName;

Code explanation

The explanation of the above query is as follows:

  • Lines 1–2: We select employee names from the Employees table, aliased as e. The data is retrieved from the Employees table.

  • Lines 3–4: We perform an INNER JOIN with the Projects table, aliased as p, on the EmpID column to combine employee and project data.

  • Line 5: We filter the results to include only those projects where the SkillID is NULL.

  • Line 6: We group the results by employee ID and name to ensure that each employee is listed only once in the final output.

In the transformed query, the INNER JOIN operation replaces the subquery. This approach often performs better and is easier to understand because it directly shows the relationship between the tables.

Example 2: Listing projects with associated employee names

Let’s find projects with associated employee names. Have a look at the following query:

SELECT (SELECT e.EmpName
FROM Employees AS e
WHERE e.EmpID = p.EmpID) AS EmpName,
ProjectName
FROM Projects AS p
WHERE p.EmpID IS NOT NULL;

Code explanation

The explanation of the query is given below:

  • Lines 1–4: The SELECT query selects EmpName, coming from subquery, and ProjectName from Projects, respectively. The e.EmpName refers to the EmpName column from the Employees table (aliased as e) and the p.EmpID refers to the EmpID column from the Projects table (aliased as p).

  • Line 5: The data is retrieved from the Projects table.

  • Line 6: The WHERE clause ensures that only those rows are selected where some employee is assigned to the project.

We’ll transform the previous subquery into a join. In this example, we’ll again use an INNER JOIN to achieve the same result. Here’s the equivalent query using a join:

SELECT e.EmpName, p.ProjectName
FROM Projects p
INNER JOIN Employees AS e
ON p.EmpID = e.EmpID;

Code explanation

The explanation of the query is given below:

  • Line 1: We select employee names from the Employees table and project names from the Projects table, respectively.

  • Line 2: The data is retrieved from the Projects table.

  • Lines 3–4: We perform an INNER JOIN with the Employees table, aliased as e, on the EmpID column to combine employee and project data.

In the transformed query, the INNER JOIN operation replaces the subquery. This approach again shows the relationship between the tables.

Benefits of using joins over subqueries

Using joins instead of subqueries can offer several advantages:

Key Benefits

Description

Performance Improvements

Joins are often faster than subqueries, especially with proper indexing.

Readability

Joins can make SQL queries easier to read and understand by clearly defining the relationships between tables.

Maintainability

Queries with joins are generally easier to maintain and update compared to complex subqueries.

A wrong join condition can lead to wrong results. Ensure that your join conditions are appropriate and align with the intended query purpose. You will need to verify the results of both queries to ensure their correctness.

Conclusion

In conclusion, both subqueries and joins are useful tools for combining data from different tables in a database. While subqueries can be handy for certain tasks, joins are generally more straightforward and efficient. Understanding when to use each method can make our database queries more effective and data retrieval faster. In most cases, joins will help us get the job done with less hassle and better performance. Ultimately, joins can improve our database queries’ performance.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


Can all subqueries be written as joins?

Mostly, all subqueries can be transformed into joins. However, some subqueries are designed for specific tasks, especially those that return single values or require calculations that are more straightforward to express as subqueries.


Which join is fastest in SQL?

Inner join is fastest in SQL.


Why avoid subquery?

Subqueries can lead to slower performance and reduced readability. Joins are usually more efficient and clearer, especially in complex queries.


Are there any situations where subqueries are preferable to joins?

Yes, subqueries can be preferable when you need to perform complex calculations or filtering that is easier to express in a nested format, or when you want to isolate specific operations without affecting the main query’s structure.


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved