Tier 2 · Core SQL

LEFT JOIN and RIGHT JOIN in SQL

By Owen Middleton · Updated September 2026 · Examples run on PostgreSQL 17

What are LEFT JOIN and RIGHT JOIN in SQL?

LEFT JOIN keeps every row from the left table, whether or not it finds a match in the right table.

You're building a customer report and you need to see all customers — including the ones who haven't placed any orders yet. INNER JOIN would silently drop customers with no orders, because there's nothing to match them against in the orders table. LEFT JOIN keeps every customer. Where there's no matching order, the order columns come back as NULL.

That's the core distinction: INNER JOIN only returns rows with matches on both sides; LEFT JOIN returns everything from the left side plus any matches from the right.

How do you write a LEFT JOIN in SQL?

Here's what it looks like. All customers, with their orders where they exist:

SELECT c.name, o.id AS order_id, o.total_amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id

Customers with orders get rows showing both customer and order data. Customers with no orders still appear — one row per customer, with order_id and total_amount as NULL.

How do you find rows with no match using LEFT JOIN?

The NULL on the right side becomes a tool. You can use WHERE right_table.id IS NULL to find exactly the rows with no match:

SELECT c.name
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE o.id IS NULL

This returns customers with no orders at all. The join finds the unmatched rows; the WHERE filter keeps only those. It's the standard pattern for gap analysis — finding records in one table with nothing corresponding in another.

What is the difference between LEFT JOIN and RIGHT JOIN?

RIGHT JOIN is the same logic flipped: every row from the right table is kept, with NULLs filling the left side where there's no match. In practice, most analysts flip the table order and use LEFT JOIN instead of writing RIGHT JOIN — it reads more naturally to keep the main table on the left.

SELECT cat.name AS category_name, p.name AS product_name
FROM products p
RIGHT JOIN categories cat ON p.category_id = cat.id

Every category appears, even ones with no products. Products with no category are excluded because categories is the right-side table being preserved.

Which table does a LEFT JOIN actually keep?

The one thing that trips people up: confusing which side is being preserved.

In FROM A LEFT JOIN B, all rows in A survive — A is the left table. In FROM A RIGHT JOIN B, all rows in B survive — B is the right table. When a result is missing rows you expected, check which table is on the preserved side and whether it should be.

Check your understanding

You write: FROM customers c LEFT JOIN orders o ON c.id = o.customer_id. Which rows are guaranteed to appear?

Practice LEFT JOIN and RIGHT JOIN in SQL

Practice · easy ecommerce · Brightlane

Brightlane's customer success team needs a list of every registered customer alongside any orders they have placed. Customers who have not yet placed any orders must still appear in the list.

Write a query to return each customer's name, order ID, and order total. Order columns will be missing for customers who have placed no orders.

Assumptions:

  • The customers table contains every customer Brightlane has on file.
  • The orders table contains every order; customer_id on each order points to a customer.
  • Some customers have placed no orders. Those customers must still appear in the result, with the order columns missing.

Output:

  • One row per customer-order pair, plus one row per customer with no orders, with columns name, order_id, and total_amount. Order columns will be missing for customers with no orders.
Schema · ecommerce5 tables? = nullable
categories
idinteger
nametext
parent_id?integer
products
idinteger
nametext
category_id?integer
pricenumeric
stock_qtyinteger
attributes?jsonb
order_items
idinteger
order_id?integer
product_id?integer
quantityinteger
unit_pricenumeric
customers
idinteger
nametext
emailtext
city?text
countrytext
created_attimestamptz
is_activeboolean
orders
idinteger
customer_id?integer
ordered_attimestamptz
statustext
total_amountnumeric

Run previews · Check grades

Write a query, then run it to see results here.

Worked solution

The full breakdown walks through the shape, each clause, why this approach beats the alternatives, and the trap to avoid.

See the full worked solution
In the game

Station Zero, our free browser SQL game, teaches this concept inside a story. No signup.

hunt an anti-join in Station Zero

9 LEFT JOIN and RIGHT JOIN practice problems

Start learning to practice all 9 LEFT JOIN and RIGHT JOIN problems, with instant grading and mastery tracking.

Common questions about LEFT JOIN and RIGHT JOIN

Why does my LEFT JOIN return more rows than the left table?

Because a left row matching several right rows produces one output row per match. A LEFT JOIN guarantees that every left row appears at least once, not exactly once, so a customer with five orders arrives as five rows.

Can a LEFT JOIN ever return fewer rows than the left table?

Not from the join itself, which keeps every left row whether or not it matches. A filter can still remove them afterwards, and a WHERE clause testing a right-side column is the usual way that happens by accident.

Is RIGHT JOIN ever the better choice?

Rarely. It does the same work as a LEFT JOIN with the tables swapped, and most people read a query faster when the table being preserved is the one named first. Reach for it when rewriting the FROM clause would make the query harder to follow.

How you actually get good at SQL

Reading explains SQL. Writing it, over and over with instant feedback, is what makes you fluent.

That's the whole SQLMaxx loop: 600+ real problems, instant AI feedback, mastery you can actually see, and spaced review that won't let you forget.

A stack of SQL practice problem cards, the top card showing an employees table.
615 problems · 66 concepts

Real problems. Not toy examples.

615 hand-built problems spanning all 66 concepts, from basic SELECTs to window functions, built on real schemas and real business questions, the kind you'll actually get asked on the job. Enough reps to make SQL automatic.

A retro computer showing a SQL query marked correct with a green checkmark.
Instant AI feedback

Write a query. Know if it's right in one second.

No copying an answer and hoping it clicked. The AI grader checks your real query against real data, catches exactly what's wrong, and explains the fix in plain English, like a senior analyst reading over your shoulder on every problem.

A circular mastery progress dial filling from blue to green, the SQLMaxx diamond at its center.
Mastery tracking

Stop guessing whether you actually know it.

SQLMaxx tracks every concept and shows you what you've mastered and what's still shaky. Your skills fill in one concept at a time, so 'I think I get joins' becomes something you can prove.

A SQL query editor circled by a blue return arrow with a clock, scheduled to come back for review.
Spaced review

Learn it once. Keep it for good.

Most of what you learn this week fades by next week. So when a concept comes due for review, SQLMaxx hands you a fresh problem to solve from a blank editor, not a flashcard to re-read. A research-backed spaced-repetition algorithm (FSRS) times each return for right before you'd forget, so your SQL is still there months later, when the interview or the job actually needs it.