Table: Customers
+---------------+---------+ | Column Name | Type | +---------------+---------+ | customer_id | int | | customer_name | varchar | +---------------+---------+ customer_id is the column with unique values for this table. Each row of this table contains the name and the id customer.
Write a solution to find the missing customer IDs. The missing IDs are ones that are not in the Customers table but are in the range between 1 and the maximum customer_id present in the table.
Notice that the maximum customer_id will not exceed 100.
Return the result table ordered by ids in ascending order.
The result format is in the following example.
Example 1:
Input: Customers table: +-------------+---------------+ | customer_id | customer_name | +-------------+---------------+ | 1 | Alice | | 4 | Bob | | 5 | Charlie | +-------------+---------------+ Output: +-----+ | ids | +-----+ | 2 | | 3 | +-----+ Explanation: The maximum customer_id present in the table is 5, so in the range [1,5], IDs 2 and 3 are missing from the table.
Problem Overview: The table contains customer IDs that should form a continuous sequence starting from 1, but some rows are missing. The task is to return every ID that does not appear in the table while staying within the existing ID range.
Approach 1: Recursive Sequence + LEFT JOIN (O(n) time, O(n) space)
The key idea is to generate the full sequence of expected IDs and compare it with the existing rows. In MySQL, a WITH RECURSIVE CTE builds numbers starting from 1 and continues until the maximum ID present in the table. After generating this sequence, perform a LEFT JOIN with the customer table and filter rows where the join result is NULL. Those represent IDs that were never inserted. This approach works well because it explicitly constructs the expected dataset, making the gap detection trivial. The recursive generation and join each scan roughly n elements, giving O(n) time complexity and O(n) auxiliary space for the generated sequence.
Approach 2: Numbers Table or Prebuilt Sequence (O(n) time, O(1) extra space)
If the database already has a numbers table (or a system table used to generate ranges), you can avoid recursion entirely. Join the numbers table containing values from 1 to MAX(id) against the customer table using a LEFT JOIN, then filter for rows where the customer ID is missing. This approach is common in production analytics environments where a permanent sequence table exists. Since the range is precomputed, the query mainly performs a scan and join operation, keeping time complexity around O(n) and requiring minimal additional memory.
Both strategies rely on the same insight: detecting gaps requires comparing the current dataset against the complete expected sequence. SQL itself does not naturally produce ranges, so the solution focuses on generating that sequence first, then using relational operations to expose the missing values.
Recommended for interviews: The recursive CTE solution is the most commonly expected answer. It demonstrates strong SQL fundamentals: sequence generation, recursion, and LEFT JOIN filtering. Interviewers want to see that you can model missing data problems by constructing the reference dataset first. Understanding this pattern is useful across many database and SQL problems, especially when working with sequences, logs, or ordered identifiers.
MySQL
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Recursive CTE + LEFT JOIN | O(n) | O(n) | General case in MySQL when you must generate the sequence dynamically |
| Numbers Table + LEFT JOIN | O(n) | O(1) | When a prebuilt numbers/sequence table already exists in the database |
AMAZON LeetCode Medium 1613 “Find the Missing IDs" Interview SQL Question Explanation | EDS • Everyday Data Science • 1,813 views views
Watch 2 more video solutions →Practice Find the Missing IDs with our built-in code editor and test cases.
Practice on FleetCode