Subqueries with EXISTS in PostgreSQL - Time & Space Complexity
When using EXISTS in SQL, we want to know how the query time changes as the data grows.
We ask: How many checks does the database do as tables get bigger?
Analyze the time complexity of the following code snippet.
SELECT customer_id
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
);
This query finds customers who have at least one order by checking if orders exist for each customer.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: For each customer, the database checks if there is at least one matching order.
- How many times: Once per customer row in the outer query.
As the number of customers grows, the database does more checks for orders.
| Input Size (n customers) | Approx. Operations |
|---|---|
| 10 | Checks for orders 10 times |
| 100 | Checks for orders 100 times |
| 1000 | Checks for orders 1000 times |
Pattern observation: The number of checks grows directly with the number of customers.
Time Complexity: O(n)
This means the time grows linearly with the number of customers checked.
[X] Wrong: "EXISTS checks all orders for every customer, so it's always very slow."
[OK] Correct: The database stops checking orders as soon as it finds one match, so it doesn't always scan all orders.
Understanding how EXISTS works helps you explain query efficiency clearly and shows you know how databases handle checks smartly.
"What if we replaced EXISTS with IN? How would the time complexity change?"
Practice
EXISTS keyword do in a SQL query?Solution
Step 1: Understand the purpose of EXISTS
TheEXISTSkeyword is used to check if a subquery returns any rows. It returns true if there is at least one row, otherwise false.Step 2: Compare with other options
Counting rows, joining tables, or deleting rows are different SQL operations unrelated toEXISTS.Final Answer:
Checks if a subquery returns any rows and returns true or false -> Option AQuick Check:
EXISTS = true if subquery has rows [OK]
- Confusing EXISTS with COUNT
- Thinking EXISTS joins tables
- Assuming EXISTS deletes data
EXISTS in a WHERE clause?Solution
Step 1: Check correct EXISTS syntax
The correct syntax requiresEXISTSfollowed by a subquery enclosed in parentheses.Step 2: Validate each option
WHERE EXISTS (SELECT * FROM orders WHERE customer_id = customers.id) uses parentheses correctly. The other options have syntax errors or incorrect keywords.Final Answer:
WHERE EXISTS (SELECT * FROM orders WHERE customer_id = customers.id) -> Option CQuick Check:
EXISTS needs parentheses around subquery [OK]
- Omitting parentheses after EXISTS
- Using '=' or 'IN' with EXISTS
- Writing subquery outside parentheses
customers(id, name) and orders(id, customer_id), what does this query return?SELECT name FROM customers WHERE EXISTS (SELECT 1 FROM orders WHERE orders.customer_id = customers.id);
Solution
Step 1: Understand the EXISTS subquery
The subquery checks if there is at least one order withcustomer_idmatching the customer'sid.Step 2: Determine the main query result
The main query selects customer names only if the subquery returns rows, meaning the customer has orders.Final Answer:
All customers who have placed at least one order -> Option BQuick Check:
EXISTS filters customers with orders [OK]
- Thinking it returns all customers
- Confusing with JOIN returning orders
- Assuming syntax error in subquery
SELECT id FROM customers WHERE EXISTS SELECT * FROM orders WHERE orders.customer_id = customers.id;
Solution
Step 1: Check EXISTS syntax
TheEXISTSkeyword must be followed by a subquery enclosed in parentheses.Step 2: Identify the error in the query
The query misses parentheses around the subquery, causing a syntax error.Final Answer:
Missing parentheses around the subquery after EXISTS -> Option DQuick Check:
EXISTS requires parentheses around subquery [OK]
- Omitting parentheses after EXISTS
- Thinking SELECT * is invalid in EXISTS
- Confusing alias usage
EXISTS to achieve this?A) SELECT name FROM customers WHERE EXISTS (SELECT 1 FROM orders WHERE orders.customer_id = customers.id AND order_date >= CURRENT_DATE - INTERVAL '30 days'); B) SELECT name FROM customers WHERE EXISTS (SELECT 1 FROM orders WHERE orders.customer_id = customers.id AND order_date <= CURRENT_DATE - INTERVAL '30 days'); C) SELECT name FROM customers WHERE EXISTS (SELECT 1 FROM orders WHERE orders.customer_id = customers.id); D) SELECT name FROM customers WHERE EXISTS (SELECT 1 FROM orders WHERE order_date >= CURRENT_DATE - INTERVAL '30 days');
Solution
Step 1: Understand the date filter requirement
We want customers with orders placed in the last 30 days, so the order date must be >= current date minus 30 days.Step 2: Analyze each query option
Select customers with orders in last 30 days using correct date filter correctly filters orders by customer and date. Select customers with orders older than 30 days filters orders older than 30 days. Select customers with any orders regardless of date ignores date. Select customers if any order in last 30 days ignoring customer link ignores customer link.Final Answer:
Select customers with orders in last 30 days using correct date filter -> Option AQuick Check:
EXISTS with date filter and customer match [OK]
- Using wrong date comparison operator
- Forgetting to link orders to customers
- Filtering orders without customer condition
Ready to prove it?
Pass the test and this pattern moves unknown
