SQL JOINs Explained: How to Combine Data from Multiple Tables

Learn how SQL JOINs work and when to use INNER, LEFT, RIGHT and FULL joins to combine data from related database tables.

Share on Linkedin Share on WhatsApp

Estimated reading time: 5 minutes

Article image SQL JOINs Explained: How to Combine Data from Multiple Tables

In a relational database, information is rarely stored in a single place. Customers live in one table, their orders in another, and the products they buy in yet another. To answer a simple question like “which customers ordered which products,” you need a way to bring these tables together. That is exactly what SQL JOINs do.

Understanding joins is one of the most valuable skills for anyone working with data. In this article, we will break down how joins work and explore the main types with clear, practical examples.

Why do we split data into separate tables?

Relational databases are designed to avoid repeating the same information over and over. Instead of writing a customer’s full name and address on every single order, we store the customer once and link each order to that customer through an identifier, usually called a key.

  • A primary key uniquely identifies each row in a table (for example, a customer ID).
  • A foreign key is a column in one table that points to the primary key of another table.

Joins use these keys to match rows from different tables and present them as if they belonged to a single result.

The basic structure of a JOIN

Most joins follow the same simple pattern: you tell the database which two tables to combine and on which columns they should match.

SELECT customers.name, orders.total
FROM customers
JOIN orders
  ON customers.id = orders.customer_id;

Here, the database looks at each row in customers and finds the matching rows in orders where the IDs line up. The result is a combined table showing customer names next to their order totals.

The main types of JOINs

The difference between join types comes down to one question: what should happen to rows that do not have a match in the other table?

INNER JOIN

An INNER JOIN returns only the rows that have a match in both tables. If a customer has no orders, they simply will not appear in the result. This is the most common join and a good default when you only care about records that are connected.

LEFT JOIN

A LEFT JOIN returns all rows from the left (first) table, plus any matching rows from the right table. When there is no match, the columns from the right table are filled with empty values (NULL). This is perfect for questions like “list all customers, including those who have never placed an order.”

RIGHT JOIN

A RIGHT JOIN is the mirror image of a LEFT JOIN: it keeps all rows from the right table and fills in NULLs where the left table has no match. In practice, many developers simply rewrite these as LEFT JOINs by swapping the table order, but it is useful to know both exist.

FULL JOIN

A FULL JOIN (also called FULL OUTER JOIN) returns all rows from both tables, matching them where possible and using NULLs where there is no match on either side. It is helpful when you want a complete picture that includes unmatched records from both tables.

A quick comparison

Join typeKeeps unmatched left rows?Keeps unmatched right rows?
INNER JOINNoNo
LEFT JOINYesNo
RIGHT JOINNoYes
FULL JOINYesYes

Common mistakes to avoid

  • Forgetting the ON condition: without it, the database may combine every row with every other row, producing a huge and meaningless result.
  • Joining on the wrong columns: always make sure you are matching a foreign key to the correct primary key.
  • Ignoring NULLs: outer joins introduce empty values, so remember to handle them when filtering or calculating totals.

Putting it into practice

Joins become intuitive once you experiment with them. Try creating two small tables, filling them with a few rows, and running each type of join to see how the results change. Pay attention to which rows appear and which disappear, and you will quickly build a mental model of how the data connects.

If you want to deepen your understanding of databases and SQL, explore the free database and programming courses available on Cursa. They offer hands-on lessons that take you from writing your first query to designing complete data models.

SQL JOINs Explained: How to Combine Data from Multiple Tables

Learn how SQL JOINs work and when to use INNER, LEFT, RIGHT and FULL joins to combine data from related database tables.

Variables and Data Types Explained: How Programs Store Information

A beginner-friendly guide to variables and data types: what they are, the main types, and how programs store and use information.

Understanding Python Lists: A Beginner’s Guide

Learn what Python lists are, how to create and modify them, and the most useful methods every beginner should know.

SQL JOINs Explained: INNER, LEFT, RIGHT and FULL, Without the Confusion

A clear, practical guide to SQL JOINs: what INNER, LEFT, RIGHT and FULL actually return, and the mistakes that quietly break queries.

Essential Excel Functions Every Beginner Should Learn

Master the most useful Excel functions for beginners, from SUM and AVERAGE to IF and VLOOKUP, with clear examples to speed up your everyday work.

Getting Started with Drones: A Beginner’s Guide to Flight Basics

A practical introduction to flying your first drone: controls, safety rules, and beginner tips.

From Script to System: How to Pick the Right Language Features in Python, Ruby, Java, and C

Learn how to choose the right language features in Python, Ruby, Java, and C for scripting, APIs, performance, and maintainable systems.

Build a Strong Programming Foundation: Data Structures and Algorithms in Python, Ruby, Java, and C

Learn Data Structures and Algorithms in Python, Ruby, Java, and C to build transferable programming skills beyond syntax.