Products With Zero Sales
Find products that never sold.
The challenge runs on the SQLabHub practice database (SQLite) and uses the products and order_items tables. You can solve it in the browser, with nothing to install.
The task
Find products that never sold.
A correct answer returns 1 row with 10 columns: id, name, category, price, cost, stock, sku, status, rating, review_count.
Tables used in this challenge
products 120 rows
id INTEGER (PK) · name TEXT · category TEXT · price REAL · cost REAL · stock INTEGER · sku TEXT · status TEXT · rating REAL · review_count INTEGER
| id | name | category | price | cost | stock | sku | status | rating | review_count |
|---|---|---|---|---|---|---|---|---|---|
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 | name | category | price | cost | stock | sku | status | rating | review_count |
|---|---|---|---|---|---|---|---|---|---|
The complete result: 1 row. This is the output of the model solution on the practice database.
What you practise
- Filtering rows with a WHERE condition
- Testing for missing values with IS NULL and IS NOT NULL
- Keeping every row of the left table with LEFT JOIN, matched or not
- Finding rows with no match using LEFT JOIN … IS NULL
Hint and approach
Try the challenge first. Open these only when you need them.
Show the hint
LEFT JOIN
Show the step-by-step approach
How the model solution is built, in the order the database evaluates it:
- Read from the
productstable. - LEFT JOIN
order_itemsonproducts.id=order_items.product_id. Rows from the left side that have no match are kept, with NULL in the joined columns. - Keep only the rows where the joined
order_itemscolumns are NULL. Those are the rows that found no match in the join. - Return every column of
products.
Model solution
Checking your session…
What to watch for
- Anti join. Test a column of the joined table that can never be NULL in a real row, normally its primary key. Testing a nullable column also returns matched rows where that column happens to be empty.
- LEFT JOIN. A WHERE condition on the right-hand table removes the unmatched rows and turns the LEFT JOIN back into an inner join. Conditions on that table go in the ON clause.
- IS NULL. Comparing with = NULL or <> NULL never matches any row. NULL has to be tested with IS NULL or IS NOT NULL.
Related SQL challenges
- Find Customers Who Never Placed an OrderSimilar levelHard
- Find Each Employee's Level in the Hierarchy with Self JoinsSimilar levelHard
- Find Shipped Orders with IS NOT NULLEasierEasy
- Find Unshipped Orders with IS NULLEasierEasy
- Build a Product Performance Report with Two CTEsSimilar levelHard
Keep learning
- Lesson: LEFT JOIN
- Lesson: IS NULL
- Lesson: WHERE Clause
- All SQL practice challenges, by difficulty and topic
- SQL interview questions with answers
- SQL Playground: run any query on the same database