AdvancedCTEs & Recursive

Classic: find all customers with no orders (multiple methods)

The query

SQL
-- Method 1: LEFT JOIN anti-join
SELECT c.name FROM customers c
LEFT JOIN orders o ON c.cust_id = o.cust_id
WHERE o.order_id IS NULL;

-- Method 2: NOT IN (beware NULL in subquery!)
SELECT name FROM customers
WHERE cust_id NOT IN (
  SELECT DISTINCT cust_id FROM orders WHERE cust_id IS NOT NULL
);

-- Method 3: NOT EXISTS (safest)
SELECT name FROM customers c
WHERE NOT EXISTS (
  SELECT 1 FROM orders o WHERE o.cust_id = c.cust_id
);

-- Method 4: EXCEPT
SELECT cust_id FROM customers
EXCEPT
SELECT DISTINCT cust_id FROM orders;
Tested against PostgreSQL 16

Note

Four methods for same result. NOT EXISTS is usually fastest. NOT IN fails with NULLs in subquery. EXCEPT is elegant.

Tables referenced