183. Customers Who Never Order
Description
Table: Customers
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+ id is the primary key (column with unique values) for this table. Each row of this table indicates the ID and name of a customer.
Table: Orders
+-------------+------+ | Column Name | Type | +-------------+------+ | id | int | | customerId | int | +-------------+------+ id is the primary key (column with unique values) for this table. customerId is a foreign key (reference columns) of the ID from the Customers table. Each row of this table indicates the ID of an order and the ID of the customer who ordered it.
Write a solution to find all customers who never order anything.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input: Customers table: +----+-------+ | id | name | +----+-------+ | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | +----+-------+ Orders table: +----+------------+ | id | customerId | +----+------------+ | 1 | 3 | | 2 | 1 | +----+------------+ Output: +-----------+ | Customers | +-----------+ | Henry | | Max | +-----------+
Solutions
Solution 1: NOT IN
Thinking
Customers with no orders are those whose \(\textit{id}\) is outside the \(\textit{customerId}\) set. \(\textit{NOT IN}\) is that set difference. Watch the empty-list semantics of \(\textit{NOT IN}\) on some engines.
List all customer IDs of existing orders, and use NOT IN to find customers who are not in the list.
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 | |
Solution 2: LEFT JOIN
Thinking
Solution 1 is awkward on a large subquery. A left join to orders, keeping rows whose \(\textit{customerId}\) is null, avoids the \(\textit{NOT IN}\)/\(\textit{NULL}\) trap and can use a join plan.
Use LEFT JOIN to join the tables and return the data where CustomerId is NULL.
1 2 3 4 5 6 | |