So far, we have explored the mechanics of different join types. In this lesson, we will move beyond the basics and look at how to apply joins to solve common business problems, handle multiple tables, and combine joins with aggregation.
In complex databases, the data you need is often spread across three or more tables connected by junction tables.
Scenario: We want to see a list of actors and the titles of the films they have appeared in.
This requires three tables: actor, film_actor (the bridge), and film.
SELECT
a.first_name,
a.last_name,
f.title
FROM
actor AS a
INNER JOIN
film_actor AS fa ON a.actor_id = fa.actor_id
INNER JOIN
film AS f ON fa.film_id = f.film_id
ORDER BY
a.last_name
LIMIT 10;
How it works:
JOIN creates a new virtual table that the next JOIN can use.One of the most powerful uses of joins is calculating statistics across related tables. You can use functions like COUNT, SUM, and AVG after joining.
Scenario: Calculate the total amount spent by each customer.
SELECT
c.first_name,
c.last_name,
SUM(p.amount) AS total_spent
FROM
customer AS c
INNER JOIN
payment AS p ON c.customer_id = p.customer_id
GROUP BY
c.customer_id, c.first_name, c.last_name
ORDER BY
total_spent DESC;
Note: When using GROUP BY with joins, always include the primary key (customer_id) to ensure unique results if two customers have the same name.
We can use LEFT JOIN combined with a WHERE clause to find records that do not have a corresponding entry in another table.
Scenario: Find all films that are currently NOT in our inventory (meaning we have the record but no physical copies).
SELECT
f.title
FROM
film AS f
LEFT JOIN
inventory AS i ON f.film_id = i.film_id
WHERE
i.inventory_id IS NULL;
A common mistake is putting a filter in the WHERE clause when using a LEFT JOIN, which accidentally turns it back into an INNER JOIN.
Incorrect:
-- This removes customers with no payments because p.payment_date is checked after the join
SELECT c.last_name, p.amount
FROM customer c
LEFT JOIN payment p ON c.customer_id = p.customer_id
WHERE p.payment_date > '2005-08-01';
Correct (keeping all customers):
-- This keeps all customers but only joins payment data that matches the date
SELECT c.last_name, p.amount
FROM customer c
LEFT JOIN payment p ON c.customer_id = p.customer_id
AND p.payment_date > '2005-08-01';
JOIN statements.JOIN with GROUP BY allows for complex reporting across business entities.LEFT JOIN ... WHERE ... IS NULL to find gaps in your data.ON vs. WHERE) when working with outer joins.