N022-H2 Tier 2 · Core SQL · hard ecommerce · Brightlane

Return the customer name, product name, category name, and quantity for every line item

Part of Joining Multiple Tables in SQL

The problem

Brightlane's operations team wants a complete line-item report linking every order to the purchasing customer, the product bought, and that product's category. Some products do not have an assigned category — those line items must still appear in the output, with the category name missing.

Write a query to return the customer name, product name, category name, and quantity for every line item.

Assumptions:

  • The chain reaches: orderscustomers, ordersorder_itemsproducts, then productscategories.
  • Every order has a customer; every order line has an order and a product; these relationships are clean one-to-many.
  • A product may have an unresolved category_id. Those line items must still appear in the result, with the category name missing.

Output:

  • One row per line item, with columns customer_name, product_name, category_name, and quantity. Rows for line items with no resolving category will have a missing category_name.
Schema · ecommerce 5 tables
categories
id integer
name text
parent_id? integer
products
id integer
name text
category_id integer
price numeric
stock_qty integer
attributes? jsonb
order_items
id integer
order_id integer
product_id integer
quantity integer
unit_price numeric
customers
id integer
name text
email text
city? text
country text
created_at timestamptz
is_active boolean
orders
id integer
customer_id integer
ordered_at timestamptz
status text
total_amount numeric

Run previews · Check grades

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

Worked solution Try it yourself first
Solution query
SELECT
  c.name AS customer_name,
  p.name AS product_name,
  cat.name AS category_name,
  oi.quantity
FROM
  orders o
  JOIN customers c ON o.customer_id = c.id
  JOIN order_items oi ON o.id = oi.order_id
  JOIN products p ON oi.product_id = p.id
  LEFT JOIN categories cat ON p.category_id = cat.id

The shape

Three INNER JOINs carry the chain through the relationships the prompt guarantees. One LEFT JOIN on the last hop preserves line items whose product has no resolving category. The mixed chain is the literal expression of the prompt's contract: every order has a customer, every line has a product, but a product may have no category.

Clause by clause

  • SELECT c.name AS customer_name, p.name AS product_name, cat.name AS category_name, oi.quantity pulls one column from each of four tables. The alias prefix on every reference keeps the three name columns straight, and cat is used rather than c for categories because c is already taken.
  • FROM orders o anchors the chain.
  • JOIN customers c ON o.customer_id = c.id is inner because every order has a customer.
  • JOIN order_items oi ON o.id = oi.order_id is inner because every line item belongs to an order. This is the row-multiplying step.
  • JOIN products p ON oi.product_id = p.id is inner because every line item points at a real product.
  • LEFT JOIN categories cat ON p.category_id = cat.id is left because a product may have no resolving category. Line items whose product has no category survive, with cat.name set to NULL.

Why this and not all LEFT JOINs

LEFT JOIN everywhere would still return the right rows on this dataset, because the other three relationships are guaranteed clean. But the join type is meant to encode that guarantee, not paper over a missing one. INNER JOIN says the right side is required. LEFT JOIN says the right side is optional. Using LEFT JOIN for a required relationship is a small lie in the query: it tells the next reader something is optional when it isn't.

The trap

The opposite mistake is making the last hop an INNER JOIN and silently losing line items whose product has no category. There would be no error. The result would look smaller than the actual line-item population, and the missing rows would never surface unless someone counted line items directly. The way to catch it is to read every INNER JOIN in the chain and ask whether the right side is genuinely guaranteed. If not, the join type is wrong for the contract.

You practiced mixing INNER JOIN and LEFT JOIN in a single chain. Use INNER JOIN when the relationship is guaranteed; reach for LEFT JOIN only where the right side is genuinely optional.

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.

Practice, feedback, mastery, review. That's the loop that turns reading into real skill.

Start free

No account, no credit card. Start solving in under a minute.