SQL Boy
TutorialsPlayground

Format & Validate

SQL FormatterSQL MinifierSyntax Validator

Convert

JSON to SQLCSV to SQLSQL to JSONRegex to SQLExcel to SQLSQL Dialect Convertersoon

Visualize

ER Diagram GeneratorSQL Schema Diff

Generate

SQL Mock Data Generator

Analyze

SQL Query ExplainerSQL Query Analyzer

Workflow hubs

FormattingConversionSchemaAnalysis
View all tools
Daily ChallengeInterviewsCheat SheetBlog

© 2026 SQL Boy. Built for developers.

ContactPrivacyTermsAI Usage PolicyEditorial StandardsAboutRSS Feed

New conversation

What can I help with?

Ask about this page, get a hint on a challenge, or explore SQL concepts.

I know what's on this page and can give answers grounded in SQL Boy content.

Current page

Products Never Ordered

/challenges/products-never-ordered

Usage status will load after login
SQL Boy
TutorialsPlayground

Format & Validate

SQL FormatterSQL MinifierSyntax Validator

Convert

JSON to SQLCSV to SQLSQL to JSONRegex to SQLExcel to SQLSQL Dialect Convertersoon

Visualize

ER Diagram GeneratorSQL Schema Diff

Generate

SQL Mock Data Generator

Analyze

SQL Query ExplainerSQL Query Analyzer

Workflow hubs

FormattingConversionSchemaAnalysis
View all tools
Daily ChallengeInterviewsCheat SheetBlog
SQL Challenges/Products Never Ordered
Challenge DetailMediumReviewed 2026-04-20

Products Never Ordered

Find products that have never been ordered. Return their names.

JoinSubqueries

This challenge now meets the current minimum standard for sitemap inclusion and independent indexing.

2025-12-08Medium

Products Never Ordered

Find products that have never been ordered. Return their names.

Available Tables:
SQL Editor
Loading...

What This Challenge Is Testing

This is a canonical anti-join pattern. In production reporting, you often need to identify customers with no purchases, features with no usage, or catalog items with no transactions. The SQL shape is the same: keep the master set and remove anything that already has a matching fact row.

Topic Tags

JoinsSubqueriesAnalytics

Schema At A Glance

products
idname
order_items
order_idproduct_id

Solution Approaches

01

LEFT JOIN anti-join

SELECT
  p.name
FROM products p
LEFT JOIN order_items oi
  ON p.id = oi.product_id
WHERE oi.product_id IS NULL

This is the most explicit anti-join form. The LEFT JOIN preserves every product, and the NULL check keeps only those products that found no matching order rows.

02

NOT IN subquery

SELECT
  name
FROM products
WHERE id NOT IN (
  SELECT product_id
  FROM order_items
)

The subquery version is short and readable for small clean datasets. It works well when the child table column is guaranteed not to contain NULLs and you want a compact answer shape.

Common Pitfalls

The main trap is using NOT IN against a subquery that can return NULL. In that case the comparison can turn unknown and eliminate every row. The LEFT JOIN / IS NULL pattern is generally safer and easier to debug.

Frequently Asked Questions

Why is LEFT JOIN often safer than NOT IN here?

NOT IN can behave unexpectedly when the subquery includes NULLs. LEFT JOIN with an IS NULL filter expresses the anti-join directly and avoids the NULL-comparison trap.

Do duplicate rows in order_items break the answer?

No. Duplicates do not matter for the anti-join logic because the question only asks whether at least one matching order exists, not how many.

Concept Guides

Use these guides when you want the fuller explanation behind the SQL pattern this challenge is testing.

SQL Subqueries Explained: Queries Within Queries

Unlock the power of nested queries. Learn when to use subqueries in SELECT, WHERE, and FROM clauses with practical, runnable examples.

SQL EXISTS vs IN: When to Use Each (With Performance Tips)

Understand the difference between EXISTS and IN in SQL. Learn which performs better and avoid the NOT IN NULL trap.

Mastering SQL Joins: An Interactive Guide

Stop guessing what JOINs do. Learn Inner, Left, and Cross Joins with live, interactive examples and animations running right in your browser.

Topic Hubs

If this problem exposed a deeper weakness, use a topic hub to move through a curated cluster instead of random article hopping.

Advanced SQL

Advanced query patterns

Use this path when you are moving beyond beginner SELECT queries into CTEs, window functions, and conditional logic.

Practice Path

If you want the rotating practice flow, open this same question from the daily stream. If you want interview-style packaging, continue into the interview pool after this rep.

Back to ChallengesOpen In DailyBrowse Interviews

Related Challenges

Customers Who Bought All ProductsMedium

Return only the customers whose distinct purchased product set covers every product listed in the catalog.

Friend Requests I: Overall Acceptance RateMedium

Calculate overall friend request acceptance rate while separating request volume from accepted pairs cleanly.

Second Highest SalaryMedium

Find the second distinct highest salary without accidentally returning the same maximum twice.

© 2026 SQL Boy. Built for developers.

ContactPrivacyTermsAI Usage PolicyEditorial StandardsAboutRSS Feed