SQL JOINs Explained: Connecting Data Across Tables

Mohammad AmanMohammad Aman
9 min read

What are SQL JOINs?

In the world of databases, information is often stored across multiple tables to keep things organized and efficient. For example, you might have one table for employee information and another for department information. But what if you want to see which department each employee belongs to? That's where JOIN clauses come in!

A JOIN clause in SQL (Structured Query Language) is used to combine rows from two or more tables based on a related column between them. Think of it like merging two lists based on a common piece of information.

Why Use JOINs?

  • Combine Related Data: Get a complete picture by linking information spread across tables (e.g., employee names with their department names).

  • Reduce Redundancy: Storing data in separate, related tables (normalization) avoids repeating the same information, and JOINs let you bring it back together when needed.

  • Powerful Queries: Answer complex questions that require data from multiple sources within the database.

Our Sample Tables

To illustrate the different types of JOINs, let's imagine we have two tables: Employees and Departments.

Employees Table:

EmployeeIDFirstNameLastNameDepartmentID
1AliceSmith101
2MohammadAman102
3CharlieWilliams101
4DavidBrownNULL
5EveDavis102
  • Note: David Brown doesn't have a DepartmentID assigned yet.

Departments Table:

DepartmentIDDepartmentName
101Human Resources
102Engineering
103Marketing
  • Note: The Marketing department (103) currently has no employees listed in the Employees table.

Now, let's explore the different types of JOINs using these tables.

1. INNER JOIN

  • Concept: Returns only the rows where there is a match in both tables based on the join condition. If a row in one table doesn't have a corresponding match in the other table, it's excluded from the result.

  • Diagram: Imagine two overlapping circles (Venn diagram). The INNER JOIN represents the overlapping area only.

  • Syntax:

      SELECT columns
      FROM table1
      INNER JOIN table2
      ON table1.common_column = table2.common_column;
    
  • Example: Let's find all employees and their corresponding department names.

      SELECT
          E.FirstName,
          E.LastName,
          D.DepartmentName
      FROM
          Employees AS E
      INNER JOIN
          Departments AS D ON E.DepartmentID = D.DepartmentID;
    
  • Result:

    | FirstName | LastName | DepartmentName | | --- | --- | --- | | Alice | Smith | Human Resources | | Mohammad | Aman | Engineering | | Charlie | Williams | Human Resources | | Eve | Davis | Engineering |

    • Explanation: Notice David Brown is missing because his DepartmentID is NULL and doesn't match any DepartmentID in the Departments table. The Marketing department is also missing because no employee has DepartmentID 103.

2. LEFT JOIN (or LEFT OUTER JOIN)

  • Concept: Returns all rows from the left table (the first table mentioned, Employees in our example) and the matched rows from the right table (the second table, Departments). If there's no match in the right table for a row in the left table, NULL values are returned for the columns from the right table.

  • Diagram: Imagine two overlapping circles. The LEFT JOIN represents the entire left circle and the overlapping area.

  • Syntax:

      SELECT columns
      FROM table1
      LEFT JOIN table2
      ON table1.common_column = table2.common_column;
    
  • Example: Let's list all employees and their department names, making sure to include employees even if they don't have a department assigned yet.

      SELECT
          E.FirstName,
          E.LastName,
          D.DepartmentName
      FROM
          Employees AS E
      LEFT JOIN
          Departments AS D ON E.DepartmentID = D.DepartmentID;
    
  • Result:

    | FirstName | LastName | DepartmentName | | --- | --- | --- | | Alice | Smith | Human Resources | | Mohammad | Aman | Engineering | | Charlie | Williams | Human Resources | | David | Brown | NULL | | Eve | Davis | Engineering |

    • Explanation: All employees are listed. David Brown, who has a NULL DepartmentID, is included, but his DepartmentName is NULL because there's no matching department. The Marketing department is still excluded because it has no matching employees in the left table (Employees).

3. RIGHT JOIN (or RIGHT OUTER JOIN)

  • Concept: Returns all rows from the right table (the second table mentioned, Departments) and the matched rows from the left table (Employees). If there's no match in the left table for a row in the right table, NULL values are returned for the columns from the left table. It's the mirror image of a LEFT JOIN.

  • Diagram: Imagine two overlapping circles. The RIGHT JOIN represents the entire right circle and the overlapping area.

  • Syntax:

      SELECT columns
      FROM table1
      RIGHT JOIN table2
      ON table1.common_column = table2.common_column;
    
  • Example: Let's list all departments and any employees in them, making sure to include departments even if they have no employees.

      SELECT
          E.FirstName,
          E.LastName,
          D.DepartmentName
      FROM
          Employees AS E
      RIGHT JOIN
          Departments AS D ON E.DepartmentID = D.DepartmentID;
    
  • Result:

    | FirstName | LastName | DepartmentName | | --- | --- | --- | | Alice | Smith | Human Resources | | Charlie | Williams | Human Resources | | Mohammad | Aman | Engineering | | Eve | Davis | Engineering | | NULL | NULL | Marketing |

    • Explanation: All departments are listed. The Marketing department, which has no employees in the Employees table, is included, but the FirstName and LastName columns are NULL for that row. David Brown is excluded because his NULL DepartmentID doesn't match any department in the right table (Departments).

4. FULL OUTER JOIN (or FULL JOIN)

  • Concept: Returns all rows when there is a match in either the left or the right table. It combines the results of both LEFT JOIN and RIGHT JOIN. If there's no match for a row in one table, NULL values are returned for the columns from the other table.

  • Diagram: Imagine two overlapping circles. The FULL OUTER JOIN represents the entire area of both circles, including the overlapping part.

  • Syntax:

      SELECT columns
      FROM table1
      FULL OUTER JOIN table2
      ON table1.common_column = table2.common_column;
    

    (Note: Some database systems like MySQL don't directly support FULL OUTER JOIN. You might need to simulate it using a UNION of a LEFT JOIN and a RIGHT JOIN.)

  • Example: Let's list all employees and all departments, matching them where possible.

      -- Standard SQL syntax
      SELECT
          E.FirstName,
          E.LastName,
          D.DepartmentName
      FROM
          Employees AS E
      FULL OUTER JOIN
          Departments AS D ON E.DepartmentID = D.DepartmentID;
    
  • Result:

    | FirstName | LastName | DepartmentName | | --- | --- | --- | | Alice | Smith | Human Resources | | Mohammad | Aman | Engineering | | Charlie | Williams | Human Resources | | David | Brown | NULL | | Eve | Davis | Engineering | | NULL | NULL | Marketing |

    • Explanation: This result includes all employees (like David Brown with NULL department) and all departments (like Marketing with NULL employee details). It shows every row from both tables, filling in NULLs where matches don't exist on either side.

5. CROSS JOIN

  • Concept: Returns the Cartesian product of the two tables. This means every row from the first table is combined with every row from the second table. It doesn't require (or typically use) an ON clause. Be careful, as this can generate a very large number of rows!

  • Diagram: Not easily represented by a Venn diagram. Think of creating every possible pairing between items from two separate lists.

  • Syntax:

      SELECT columns
      FROM table1
      CROSS JOIN table2;
    
      -- Or the older comma syntax:
      SELECT columns
      FROM table1, table2;
    
  • Example: Combine every employee with every department (this isn't usually meaningful data on its own, but demonstrates the concept).

      SELECT
          E.FirstName,
          D.DepartmentName
      FROM
          Employees AS E
      CROSS JOIN
          Departments AS D;
    
  • Result: (Shows only the first few rows for brevity - total rows = 5 employees * 3 departments = 15 rows)

    | FirstName | DepartmentName | | --- | --- | | Alice | Human Resources | | Alice | Engineering | | Alice | Marketing | | Mohammad | Human Resources | | Mohammad | Engineering | | Mohammad | Marketing | | Charlie | Human Resources | | ... | ... | | Eve | Marketing |

    • Explanation: Each of the 5 employees is paired with each of the 3 departments, resulting in 15 rows total.

6. SELF JOIN

  • Concept: A SELF JOIN is not a different type of join syntax, but rather a regular join (usually INNER or LEFT) where a table is joined with itself. This is useful for querying hierarchical data or comparing rows within the same table. You need to use aliases to distinguish between the two instances of the same table.

  • Syntax: Uses standard JOIN syntax, but aliases the table name.

      SELECT columns
      FROM table1 AS alias1
      JOIN table1 AS alias2
      ON alias1.column = alias2.column; -- Join condition links rows within the same table
    
  • Example: Let's modify the Employees table slightly to include a ManagerID which refers back to another EmployeeID.

    Modified Employees Table:

    | EmployeeID | FirstName | LastName | DepartmentID | ManagerID | | --- | --- | --- | --- | --- | | 1 | Alice | Smith | 101 | 3 | | 2 | Mohammad | Aman | 102 | 5 | | 3 | Charlie | Williams | 101 | NULL | | 4 | David | Brown | NULL | NULL | | 5 | Eve | Davis | 102 | NULL |

    Now, let's find each employee and their manager's name.

      SELECT
          Emp.FirstName AS EmployeeFirstName,
          Emp.LastName AS EmployeeLastName,
          Mgr.FirstName AS ManagerFirstName,
          Mgr.LastName AS ManagerLastName
      FROM
          Employees AS Emp -- Alias for the employee instance
      LEFT JOIN
          Employees AS Mgr -- Alias for the manager instance
      ON Emp.ManagerID = Mgr.EmployeeID; -- Join employee's manager ID to manager's employee ID
    
  • Result:

    | EmployeeFirstName | EmployeeLastName | ManagerFirstName | ManagerLastName | | --- | --- | --- | --- | | Alice | Smith | Charlie | Williams | | Mohammad | Aman | Eve | Davis | | Charlie | Williams | NULL | NULL | | David | Brown | NULL | NULL | | Eve | Davis | NULL | NULL |

    • Explanation: We joined the Employees table to itself using aliases Emp and Mgr. The LEFT JOIN ensures all employees are listed, even those without a manager (like Charlie, David, and Eve), showing NULL for their manager's name.

Conclusion

SQL JOINs are fundamental tools for working with relational databases. By understanding the differences between INNER, LEFT, RIGHT, FULL OUTER, CROSS, and SELF joins, you can effectively combine data from multiple tables to retrieve exactly the information you need. Remember to choose the join type that best fits the relationship between your tables and the specific question you are trying to answer.

0
Subscribe to my newsletter

Read articles from Mohammad Aman directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mohammad Aman
Mohammad Aman

Full-stack developer with a good foundation in frontend, now specializing in backend development. Passionate about building efficient, scalable systems and continuously sharpening my problem-solving skills. Always learning, always evolving.