easyJOINsSubqueriesNULL handling
Customers Without Orders
List customers who have never placed an order using an anti-join.
Start practicePrompt
Customers Without Orders
Prompt
Given the customers and orders tables below, write a query that returns the name of every customer who has never placed an order.
- Each customer should appear at most once in the result.
- Only the customer
nameshould be returned — no other columns. orders.customer_idmay beNULL; such orders do not belong to any customer and must not rescue anyone.
Example
| customers | orders | ||
|---|---|---|---|
| id | name | id | customer_id |
| 1 | Alice | 1 | 1 |
| 2 | Bob | 2 | 3 |
| 3 | Carol | 3 | NULL |
| 4 | Dave |
Expected result:
| name |
|---|
| Bob |
| Dave |
Constraints
customers.idis the primary key.orders.customer_idreferencescustomers.idbut is nullable.
Tips
- This is an anti-join: keep rows from the left side that have no match on the right.
LEFT JOIN+WHERE orders.id IS NULLandNOT EXISTSare the two idiomatic forms.- If you use a subquery with
NOT IN, remember howNULLvalues behave insideNOT IN (…).
Expected concepts
- LEFT JOIN
- NOT EXISTS
- Anti-join
- NULL filtering
Schema
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id) -- NULL allowed
);
Sample data
INSERT INTO customers (id, name) VALUES
(1, 'Alice'),
(2, 'Bob'),
(3, 'Carol'),
(4, 'Dave');
INSERT INTO orders (id, customer_id) VALUES
(1, 1),
(2, 1),
(3, 3),
(4, 3);
Additional hidden fixtures are applied during validation to test edge cases.