Types of SQL JOINs Explained With Examples

Relational databases like SQL Server store data across multiple tables linked by common key values. Therefore, it's often necessary to retrieve records from two or more related tables based on specific conditions. To accomplish this, SQL Server uses the JOIN clause.

A JOIN is an SQL clause that allows you to query and retrieve data from multiple tables based on logical relationships between them. In simple terms, it tells SQL Server how to use data from one table to find matching rows in another.

Master JOINs with dbForge SQL Complete

As you progress as a database user, you'll continually need to fetch and combine data from more than one table using SQL Server JOINs. At this point, dbForge SQL Complete comes to the aid. Its code completion works excellently even for complex JOIN statements.

dbForge SQL Complete suggests a full JOIN clause based on foreign keys or conditions based on column names. These suggestions are available after the JOIN and ON keywords.

Moreover, dbForge SQL Complete can prompt a complete SQL JOIN statement when you combine tables based on foreign keys. Additionally, you can select a JOIN statement from the prompt list manually for a specific JOIN operation.

Let's have a look at various JOIN types created using dbForge SQL Complete.

Basic SQL JOIN types

SQL Server supports several JOIN types, including INNER JOIN, SELF JOIN, CROSS JOIN, and OUTER JOIN.

OUTER JOINs can further be divided into LEFT OUTER JOINs, RIGHT OUTER JOINs, and FULL OUTER JOINs.

Each JOIN type defines the way two tables are related in a query.

  • SQL INNER JOIN combines all rows that have matching values in two or more tables.
  • SQL LEFT OUTER JOIN combines all rows from the left table and only the matching rows from the right table.
  • SQL RIGHT OUTER JOIN combines all records from the right table and only the matching rows from the left table.
  • SQL SELF JOIN joins the table to itself for comparing rows within the same table.
  • SQL CROSS JOIN combines each row of the first table with each row of the second table.

INNER JOIN

An INNER JOIN returns only the records (or rows) that have matching values in both tables. It is used to retrieve data that exists in both related tables.

Inner JOIN work principle in SQL Server

The simplest query example is:

SELECT
  c.Name
 ,o.Product
FROM Customers c
INNER JOIN Orders o
  ON c.CustomerID = o.CustomerID;
  • When to use: Use SQL INNER JOIN only when you need rows that exist in both tables.
  • Pitfalls: The query excludes unmatched rows, which can cause "missing data" issues. If you need to preserve unmatched rows from one table, use LEFT JOIN instead.
  • Example scenario: Compile the list of customers who placed orders, including customer names and product names.
SELECT 
    p.FirstName + ' ' + p.LastName AS CustomerName,
    pr.Name AS Product
FROM Sales.Customer c
INNER JOIN Person.Person p
    ON c.PersonID = p.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh
    ON c.CustomerID = soh.CustomerID
INNER JOIN Sales.SalesOrderDetail sod
    ON soh.SalesOrderID = sod.SalesOrderID
INNER JOIN Production.Product pr
    ON sod.ProductID = pr.ProductID;

Inner JOIN in SQL Server

OUTER JOIN

An OUTER JOIN returns a result that includes both matching and unmatching rows from the left and right tables. If no matching rows exist for the row in the left table, the columns of the right table will contain NULLs. Correspondingly, the columns of the left table will contain NULLs if there are no matching rows for the row in the right table.

Outer JOIN work principle in SQL Server

The simplest query example is:

SELECT c.Name, o.Product 
FROM Customers c 
FULL OUTER JOIN Orders o ON c.CustomerID = o.CustomerID;
  • When to use: Use the FULL OUTER JOIN when you need a complete overview of all records, matched or not.
  • Pitfalls: Large result sets filled with NULLs can make analysis harder and cause low performance. To avoid this, use the FULL JOIN query only when absolutely needed; otherwise, stick to LEFT JOIN or INNER JOIN for efficiency.
  • Example scenario: Retrieve the list of all products in orders even if the customer information is missing.
SELECT 
    p.FirstName + ' ' + p.LastName AS CustomerName,
    pr.Name AS Product
FROM Sales.Customer c
FULL OUTER JOIN Person.Person p
    ON c.PersonID = p.BusinessEntityID
FULL OUTER JOIN Sales.SalesOrderHeader soh
    ON c.CustomerID = soh.CustomerID
FULL OUTER JOIN Sales.SalesOrderDetail sod
    ON soh.SalesOrderID = sod.SalesOrderID
FULL OUTER JOIN Production.Product pr
    ON sod.ProductID = pr.ProductID;

Outer JOIN in SQL Server

LEFT OUTER JOIN

A LEFT OUTER JOIN returns all rows from the left table and the matching rows from the right table. If there are no matches in the right table, the result will still include the left table's rows, with NULL values for the columns from the right table.

Left JOIN work principle in SQL Server

The simplest query example is:

SELECT c.Name, o.Product 
FROM Customers c 
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID;
  • When to use: Use the SQL LEFT OUTER JOIN when you want to include all rows from the left table, even without matches.
  • Pitfalls: This query may produce NULL values for missing matches. Reports or calculations may break if NULLs aren't handled. To avoid this, use COALESCE() or ISNULL() to replace NULLs with default values, e.g., COALESCE(o.Product, 'No Orders').
  • Example scenario: Get the list of all customers, even if they have not placed any orders (in that case, the Product column for the customer will contain NULL).
SELECT 
    p.FirstName + ' ' + p.LastName AS CustomerName,
    pr.Name AS Product
FROM Sales.Customer c
LEFT JOIN Person.Person p
    ON c.PersonID = p.BusinessEntityID
LEFT JOIN Sales.SalesOrderHeader soh
    ON c.CustomerID = soh.CustomerID
LEFT JOIN Sales.SalesOrderDetail sod
    ON soh.SalesOrderID = sod.SalesOrderID
LEFT JOIN Production.Product pr
    ON sod.ProductID = pr.ProductID;

Left outer JOIN in SQL Server

RIGHT OUTER JOIN

A RIGHT OUTER JOIN operates on the same principle as the LEFT OUTER JOIN, but in reverse. It returns all records from the right table and the matching records from the left table. If a row in the right table has no corresponding match in the left table, the result will still include that row, but with NULL values.

Right OUTER JOIN work principle in SQL Server

The simplest query example is:

SELECT c.Name, o.Product 
FROM Customers c 
RIGHT JOIN Orders o ON c.CustomerID = o.CustomerID;
  • When to use: SQL RIGHT OUTER JOINS are helpful in scenarios where you want to include all rows from the right table, even if there's no match.
  • Pitfalls: This query is less intuitive than LEFT JOIN. Developers may confuse the two. It is advisable to standardize on LEFT JOIN in your team and reorder tables when needed—it makes queries easier to read.
  • Example scenario: Return the list of all products that appear in orders. If the person information is missing, CustomerName will be NULL.
SELECT 
    p.FirstName + ' ' + p.LastName AS CustomerName,
    pr.Name AS Product
FROM Person.Person p
RIGHT JOIN Sales.Customer c
    ON p.BusinessEntityID = c.PersonID
RIGHT JOIN Sales.SalesOrderHeader soh
    ON c.CustomerID = soh.CustomerID
RIGHT JOIN Sales.SalesOrderDetail sod
    ON soh.SalesOrderID = sod.SalesOrderID
RIGHT JOIN Production.Product pr
    ON sod.ProductID = pr.ProductID;

Right outer JOIN in SQL Server

SELF JOIN

A SELF JOIN allows joining a table with itself. In this type of JOIN, each row is combined with other rows in the same table, as if the table were duplicated. However, it does not copy the table physically because SQL uses table aliases to create distinct references to the same table.

Self JOIN work principle in SQL Server

The simplest query example is:

SELECT e.Name AS Employee, m.Name AS Manager 
FROM Employees e 
LEFT JOIN Employees m ON e.ManagerID = m.EmpID;
  • When to use: Use the SQL SELF JOIN when you want to compare or link rows in the same table.
  • Pitfalls: With this JOIN type, it is easy to lose track of aliases (e vs m) and NULL rows may complicate reporting. To avoid this, always use clear aliases (Employee, Manager) and handle NULLs explicitly.
  • Example scenario: Match each employee with the manager. If the employee has no manager (belongs to the top management), the column will contain NULLs.
SELECT 
    epp.FirstName + ' ' + epp.LastName AS Employee,
    mpp.FirstName + ' ' + mpp.LastName AS Manager
FROM HumanResources.Employee e
LEFT JOIN HumanResources.Employee m
    ON e.OrganizationNode.GetAncestor(1) = m.OrganizationNode
LEFT JOIN Person.Person epp
    ON e.BusinessEntityID = epp.BusinessEntityID
LEFT JOIN Person.Person mpp
    ON m.BusinessEntityID = mpp.BusinessEntityID;

Self JOIN in SQL Server

CROSS JOIN

A CROSS JOIN in SQL, also known as a Cartesian join, combines each row from the first table with every row from the second table. The result is a set of all possible combinations between the two tables. Unlike other types, a CROSS JOIN does not require a joining condition.

Cross JOIN work principle in SQL Server

The simplest query example is:

SELECT c.Color, s.Size 
FROM Colors c 
CROSS JOIN Sizes s;
  • When to use: Use the SQL CROSS JOIN when you want to generate combinations of all values between two tables.
  • Pitfalls: Result size grows quickly (rows = table1 × table2), which can crash queries if tables are large. Therefore, use it only for small lookup tables or with filters (WHERE clause) to control output size.
  • Example scenario: Generate all possible combinations of color and size with no additional JOIN conditions.
SELECT 
    c.Color,
    s.Size
FROM 
    (SELECT DISTINCT Color 
     FROM Production.Product 
     WHERE Color IS NOT NULL) AS c
CROSS JOIN 
    (SELECT DISTINCT Size 
     FROM Production.Product 
     WHERE Size IS NOT NULL) AS s;

Cross JOIN in SQL Server

SQL JOINs summary

Type Syntax When to use Returns Example
INNER JOIN SELECT *
FROM A
INNER JOIN B
ON A.id = B.id;
When you need only rows that exist in both tables Rows with matching values in both tables Find customers who placed orders
LEFT JOIN SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id;
When you want all rows from the left table, even without matches All rows from the left plus matches from the right; unmatched right rows = NULL List all employees and their departments, even if some employees are not assigned
RIGHT JOIN SELECT *
FROM A
RIGHT JOIN B
ON A.id = B.id;
When you want all rows from the right table, even without matches All rows from right plus matches from left; unmatched left rows = NULL List all departments and their employees, even if some departments have no employees
FULL OUTER JOIN SELECT *
FROM A
FULL OUTER JOIN B
ON A.id = B.id;
When you need a complete set from both tables All rows from both tables; unmatched rows filled with NULLs Combine customer and supplier lists, showing all contacts
CROSS JOIN SELECT *
FROM A
CROSS JOIN B;
When you need every combination of two tables (Cartesian product) All possible row combinations Generate all possible product and category combinations
SELF JOIN SELECT a.*, b.* FROM Employees a JOIN Employees b ON a.ManagerID = b.EmpID; When comparing rows within the same table (hierarchies, relationships) Matches rows from the same table Find employees who report to the same manager

Conclusion

SQL JOINs are essential tools for retrieving and combining data from multiple tables in a database. Mastering them is a fundamental skill for any database professional. This article provides a clear overview of the basic types of SQL JOINs, their characteristics, and practical use cases, helping you grasp these core concepts quickly and with ease.

In addition, dbForge SQL Complete is a powerful assistant for working with JOINs. This robust add-in for SSMS helps you write SQL queries more efficiently. With advanced code suggestions and AI-powered query generation based on plain-language prompts, it simplifies even the most complex JOIN operations. You can try dbForge SQL Complete right away by downloading its fully functional trial and testing it with your own workload.

FAQ

What is meant by JOINs in SQL?

Joining in SQL means retrieving data from two or more tables based on a common field. In other words, JOINs combine data from multiple tables in a result table based on a related column between those tables.

Why do we use JOINs in SQL?

The purpose of JOINs in SQL is to access data from multiple tables based on logical relationships between them. JOINs are used to fetch data from database tables and represent the result dataset as a separate table.

How many types of JOINs are there in SQL?

There are four main types of JOINs in SQL: INNER JOIN, OUTER JOIN, CROSS JOIN, and SELF JOIN. OUTER JOINs can be further divided into three subtypes: LEFT OUTER JOIN, RIGHT OUTER JOIN, and FULL OUTER JOIN.

What common mistakes should you avoid with SQL JOINs?

1. Forgetting the ON clause

When you join two tables without an ON condition, every row from the first table is paired with every row from the second table. Let us consider the below Customers and Orders input tables.

CustomerID Name
1 Alice
2 Bob
OrderID CustomerID Product
101 1 Laptop
102 2 Phone

Wrong query:

SELECT *
FROM Customers, Orders;

Output (Cartesian product):

CustomerID Name OrderID CustomerID Product
1 Alice 101 1 Laptop
1 Alice 102 2 Phone
2 Bob 101 1 Laptop
2 Bob 102 2 Phone

Problem: You get 4 rows instead of 2, with meaningless combinations.

Correct query:

SELECT c.Name, o.Product
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID;

2. Wrong JOIN condition

If you run a JOIN query on unrelated columns, you'll either lose matches or create wrong ones.

Wrong query:

SELECT *
FROM Customers c
JOIN Orders o ON c.CustomerID = o.OrderID;

Why it's wrong:

  • CustomerID values are 1, 2.
  • OrderID values are 101, 102.
  • Since these numbers don't overlap, no rows will match, and you'll get an empty result set.

Correct query:

SELECT c.Name, o.Product
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID;

3. Not using aliases

When both tables have a column with the same name, the database won't know which one you mean if you don't prefix it.

Wrong query:

SELECT CustomerID, Name, Product
FROM Customers
JOIN Orders ON CustomerID = CustomerID;

This fails with "ambiguous column name" because CustomerID exists in both tables.

Correct query (using aliases):

SELECT c.CustomerID, c.Name, o.Product
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID;

4. Joining on non-indexed columns

Sometimes your JOIN query might work but run very slowly on large datasets.

Example:

SELECT c.Name, o.Product
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID;

On large tables, the database may scan the entire Orders table for each CustomerID, which is very slow.

To fix this, add an index:

CREATE INDEX idx_orders_customerid 
ON Orders(CustomerID);
What are the 3 most popular types of JOINs in SQL explained with examples?

INNER JOIN

Suppose, we have two tables: Customers (with CustomerID, Name, and CountryID columns) and Orders (with OrderID, CustomerID, and OrderDate columns). Using the INNER JOIN we can create a result table containing the CustomerID, Name, OrderID, and OrderDate columns. In such a simple way, we will be able to see who and when created an order. The tables will be matched based on the common CustomerID column, and the unmatched row won't get into the result dataset.

LEFT OUTER JOIN

Suppose, we have the Products and Orders tables that have a common ProductId column. With the help of the LEFT OUTER JOIN we can combine the two tables in a result table that will contain all the rows from the Products table and in case no records match from the Orders table, the NULL values will be shown in the OrderID column. In such a simple way, we will be able to see which products have not been ordered yet.

RIGHT OUTER JOIN

The RIGHT OUTER JOIN works similarly to the LEFT OUTER JOIN, but in the opposite direction. Let's consider the Vendors and Orders tables. Using the RIGHT OUTER JOIN we can retrieve records for all vendors showing their purchase orders. In case a vendor hasn't placed any orders yet, NULLs will be displayed in the PurchaseOrderId column.

What is the difference between UNION and JOIN in SQL Server?

Both JOIN and UNION serve to combine data; however, their distinction lies in the manner in which they execute this operation. For a full explanation, refer to UNION vs. UNION ALL in SQL Server.

How many tables can be joined in SQL Server?

SQL Server supports up to 256 tables in a single query using JOINs. However, in practice, queries with more than 5–7 JOINs are usually complex and harder to maintain. Consider breaking them into smaller queries or using Common Table Expressions (CTEs) for readability and performance.

What is the difference between LEFT and RIGHT JOIN?

A LEFT JOIN keeps all rows from the left table and adds matching rows from the right table, filling unmatched rows with NULL.

A RIGHT JOIN does the opposite: it keeps all rows from the right table and brings in the matches from the left.

Rule of thumb: LEFT = keep left, RIGHT = keep right.

Can SQL JOINs affect performance?

Yes. JOINs can significantly affect query performance, especially on large datasets.

Problems often occur when:

  • Joining on non-indexed columns
  • Using FULL JOIN or CROSS JOIN on large tables
  • Joining too many tables without filters

To improve performance:

  • Create indexes on join keys
  • Use only the necessary columns in SELECT
  • Filter data early with WHERE clauses

dbForge SQL Complete

Enjoy even the most complex JOINs with SQL Complete
Free edition available