Orders with User & Items
Find order id, user id and total items.
The challenge runs on the SQLabHub practice database (SQLite) and uses the orders and order_items tables. You can solve it in the browser, with nothing to install.
The task
Find order id, user id and total items.
A correct answer returns 200 rows with 3 columns: id, user_id, SUM(oi.quantity).
Tables used in this challenge
orders 200 rows
id INTEGER (PK) · user_id INTEGER · total REAL · discount REAL · item_count INTEGER · status TEXT · order_date TEXT · shipped_date TEXT · shipping_city TEXT · shipping_country TEXT
| id | user_id | total | discount | item_count | status | order_date | shipped_date | shipping_city | shipping_country |
|---|---|---|---|---|---|---|---|---|---|
order_items 496 rows
id INTEGER (PK) · order_id INTEGER · product_id INTEGER · quantity INTEGER · unit_price REAL · subtotal REAL
| id | order_id | product_id | quantity | unit_price | subtotal |
|---|---|---|---|---|---|
The first rows of each table are shown. See how all the tables relate on the database schema page.
Expected output
| id | user_id | SUM(oi.quantity) |
|---|---|---|
First 5 of 200 rows. This is the output of the model solution on the practice database. The task does not fix a sort order, so your rows may come back in a different order.
What you practise
- Summarising many rows into one value with COUNT, SUM, AVG, MIN or MAX
- Grouping by more than one column to get a row per combination
- Combining rows from two tables on a matching key with an inner join
Hint and approach
Try the challenge first. Open these only when you need them.
Show the hint
JOIN + GROUP BY
Show the step-by-step approach
How the model solution is built, in the order the database evaluates it:
- Read from the
orderstable. - Join
order_itemsonorders.id=order_items.order_id. - Group the rows by
orders.idandorders.user_id, so the result has one row for each combination. - For each group, compute
SUM(order_items.quantity).
Model solution
Checking your session…
What to watch for
- INNER JOIN. An inner join drops rows that have no partner on the other side, and it repeats a row once for every match, which inflates SUM and COUNT.
- GROUP BY on several columns. Each extra GROUP BY column splits the groups further. Grouping by a column that is unique per row gives back one group per row.
- Aggregate functions. Aggregates skip NULLs. AVG divides by the number of non-NULL values and COUNT(column) can be smaller than COUNT(*).
Related SQL challenges
- Count Orders per Customer per Day with a Two-Column GROUP BYSimilar levelMedium
- Join Order Items to Products to Show Product NamesSimilar levelMedium
- Add Up Order Totals with SUM()EasierEasy
- Find Products That Customers Buy More Than OnceHarderHard
- Measure Monthly Revenue Volatility per ProductHarderHard
Keep learning
- Lesson: INNER JOIN
- Lesson: GROUP BY Multiple Columns
- Lesson: Aggregate Functions
- All SQL practice challenges, by difficulty and topic
- SQL interview questions with answers
- SQL Playground: run any query on the same database