How do you find rows in one table that have no matching row in another?
Use LEFT JOIN and keep rows where the right table's key IS NULL, or use NOT EXISTS. Both are safer than NOT IN, which fails when the subquery returns a NULL.
Explain it simply
"Which students never paid the fee?" You compare the student list against the payment list and keep the students who find no partner. This is called an anti-join.
Line by line
Tables customers(id, name) and orders(id, customer_id). Find customers with no orders.
-- Option 1, LEFT JOIN plus IS NULL
SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;
-- Option 2, NOT EXISTS
SELECT c.id, c.name
FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o WHERE o.customer_id = c.id
);- In Option 1 the LEFT JOIN keeps every customer. A customer with no orders gets NULL in every
ocolumn, and the WHERE keeps exactly those rows. Test a column that is never NULL in real rows, such as the primary key. - In Option 2 the subquery runs per customer and NOT EXISTS is true when it finds nothing.
- Avoid
WHERE id NOT IN (SELECT customer_id FROM orders)ifcustomer_idcan be NULL, because then no row is returned at all.
Complexity
Time: with an index on orders.customer_id, about O(n log m) for n customers and m orders; a hash anti-join is O(n + m). Space: O(1) to O(m) for a hash table.
What to say in the interview
"I use NOT EXISTS or LEFT JOIN with IS NULL. They handle NULLs correctly and the optimizer turns both into an anti-join. I avoid NOT IN when the subquery column is nullable."