Brightlane's catalogue team needs a complete reconciliation of the product and category tables — both directions:
- Every product appears, including products whose category does not resolve (category name will be
NULL). - Every category appears, including categories with no products assigned (product name will be
NULL).
Write a query to return the product name and category name for every row in the combined view.
Assumptions:
- The
productstable contains every product in the catalogue. - The
categoriestable contains every defined category. - Some products have a
category_idthat does not resolve to any category; some categories have no products assigned.
Output:
- One row per matched product-category pair, plus one row per unmatched product (with
category_nameasNULL), plus one row per unmatched category (withproduct_nameasNULL).
Schema · ecommerce 5 tables
Run previews · Check grades
Write a query, then run it to see results here.
Worked solution Try it yourself first
SELECT
p.name AS product_name,
cat.name AS category_name
FROM
products p
FULL OUTER JOIN categories cat ON p.category_id = cat.id The shape
A FULL OUTER JOIN between products and categories keeps every row from both sides at once. Matched product-category pairs come out assembled; an orphan product comes out with category_name as NULL; an orphan category comes out with product_name as NULL. Three kinds of rows, one query.
Clause by clause
SELECT p.name AS product_name, cat.name AS category_namepicks one column from each side of the join. On matched rows both values are real; on orphan rows the missing side's column isNULL, which is the signal the catalogue team reads as a gap.FROM products p FULL OUTER JOIN categories cat ON p.category_id = cat.idis the reconciliation. TheONcondition pairs a product with its category whenevercategory_idresolves; when it doesn't, the outer join keeps the row anyway and pads the other side withNULL. BecauseFULLmakes that guarantee in both directions, a category with no products is preserved too.- No
WHERE, no filter. The catalogue team asked for the combined view — matched plus both flavors of orphan — so every row the join produces belongs in the output.
You practiced a FULL OUTER JOIN to preserve every row from both tables. The recurring shape: when neither table has a privileged role and the question is "what's on each side, including the gaps," FULL OUTER JOIN is the only join type that surfaces both kinds of unmatched rows in a single result.