N022-M2 Tier 2 · Core SQL · medium ecommerce · Brightlane

Return the customer name, product name, and category name for every line item where the product has a resolving category

Part of Joining Multiple Tables in SQL

The problem

Brightlane's merchandising team wants a complete breakdown of what customers have purchased, including the category each product belongs to.

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

Assumptions:

  • The chain reaches: orderscustomers, ordersorder_itemsproductscategories.
  • Line items whose product has no resolving category are excluded from the result.

Output:

  • One row per line item with a resolving category, with columns customer_name, product_name, and 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
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
  JOIN categories cat ON p.category_id = cat.id

The shape

Five tables, four JOINs, every one of them an inner match. The chain reaches from orders outward to customers on one side and through order_items to products to categories on the other. Line items whose product has no category_id (or whose category_id doesn't match any row in categories) drop out at the final join.

Clause by clause

  • SELECT c.name AS customer_name, p.name AS product_name, cat.name AS category_name pulls a name from three different tables. Three aliases are mandatory — without them, every reference would be ambiguous. cat rather than c for categories, because c is already taken by customers.
  • FROM orders o anchors the chain on orders.
  • JOIN customers c ON o.customer_id = c.id attaches the customer.
  • JOIN order_items oi ON o.id = oi.order_id attaches the line items. This is the row-multiplying step.
  • JOIN products p ON oi.product_id = p.id resolves each line item to its product.
  • JOIN categories cat ON p.category_id = cat.id resolves each product to its category. As an INNER JOIN, this hop silently drops any line item whose product has a missing or unmatched category_id. The prompt's contract — "where the product has a resolving category" — is exactly what this join type enforces.

Why this and not LEFT JOIN on the last hop

A LEFT JOIN would keep the line items whose products have no resolving category and show their category_name as missing. That's a different answer to a different question. The prompt scopes the result to line items with a resolving category, which is the inner-join semantic — drop the rows that don't match. The next problem (N022-H2) is the same chain with the optionality flipped, so the right join type comes from reading the prompt, not from a default.

You practiced a five-table chain composed entirely of inner matches. The shape scales without ceremony — each new table adds one more matching condition; alias discipline keeps the result readable.

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.