Bird
Raised Fist0
SQLquery~15 mins

Subquery with IN operator in SQL - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - Subquery with IN operator
What is it?
A subquery with the IN operator is a way to ask a database to find rows where a value matches any value from a list returned by another query. It lets you nest one query inside another to filter results based on multiple possible matches. This helps you write clear and powerful questions to the database without repeating code.
Why it matters
Without the IN operator combined with subqueries, you would have to manually list all possible values or write multiple queries to check each value. This would be slow, error-prone, and hard to maintain. Using subqueries with IN makes your queries flexible and efficient, especially when dealing with related data spread across tables.
Where it fits
Before learning this, you should understand basic SELECT queries and simple WHERE conditions. After mastering subqueries with IN, you can explore more complex filtering like EXISTS, JOINs, and advanced subqueries for performance tuning.
Mental Model
Core Idea
The IN operator with a subquery checks if a value exists within a set of values returned by another query.
Think of it like...
Imagine you have a guest list for a party, and you want to check if a person is invited by looking at the list. The subquery is like the guest list, and the IN operator is like checking if the person's name is on that list.
Main Query
  │
  ├─ WHERE column IN (Subquery)
  │                 │
  │                 └─ Returns list of values
  └─ Returns rows where column matches any value in list
Build-Up - 7 Steps
1
FoundationUnderstanding Basic SELECT Queries
🤔
Concept: Learn how to retrieve data from a single table using SELECT.
A SELECT query asks the database to give you rows from a table. For example, SELECT name FROM employees; returns all employee names.
Result
A list of names from the employees table.
Knowing how to select data is the first step to filtering and combining queries.
2
FoundationUsing WHERE to Filter Rows
🤔
Concept: Learn how to filter rows by conditions using WHERE.
The WHERE clause lets you pick only rows that meet a condition. For example, SELECT name FROM employees WHERE department = 'Sales'; returns names only from the Sales department.
Result
A list of employee names working in Sales.
Filtering data is essential to get meaningful results from large tables.
3
IntermediateIntroducing Subqueries
🤔
Concept: Learn how to write a query inside another query.
A subquery is a query inside parentheses that runs first. For example, SELECT name FROM employees WHERE department_id IN (SELECT id FROM departments WHERE name = 'Sales'); finds employees in the Sales department by first finding the department id.
Result
Employees who belong to the Sales department based on department id.
Subqueries let you use results from one query to filter another, making queries dynamic.
4
IntermediateUsing IN Operator with Subqueries
🤔Before reading on: do you think IN checks for a single value or multiple values from the subquery? Commit to your answer.
Concept: The IN operator checks if a value matches any value in a list returned by a subquery.
IN compares a column to a list of values. When combined with a subquery, it checks if the column's value is in the list returned by the subquery. For example, SELECT product_name FROM products WHERE category_id IN (SELECT id FROM categories WHERE name LIKE 'Electronics%'); returns products in any category starting with 'Electronics'.
Result
List of product names in categories starting with 'Electronics'.
Understanding that IN works with multiple values from subqueries allows flexible filtering without manually listing values.
5
IntermediateComparing IN with Multiple OR Conditions
🤔Before reading on: is using IN with a subquery more efficient or less efficient than multiple OR conditions? Commit to your answer.
Concept: IN with subqueries replaces many OR conditions, making queries simpler and often more efficient.
Instead of writing WHERE category_id = 1 OR category_id = 2 OR category_id = 3, you can write WHERE category_id IN (SELECT id FROM categories WHERE id IN (1,2,3)). This is cleaner and easier to maintain.
Result
Same filtered results but with simpler query syntax.
Using IN reduces complexity and potential errors in queries with many conditions.
6
AdvancedHandling NULLs in Subqueries with IN
🤔Before reading on: do you think NULL values in the subquery list affect the IN operator's behavior? Commit to your answer.
Concept: NULL values in subquery results can cause unexpected behavior with IN, because NULL means unknown.
If the subquery returns NULL among values, the IN condition may not return rows you expect. For example, WHERE id IN (1, NULL) can behave differently depending on the database. To avoid this, filter out NULLs in the subquery using WHERE column IS NOT NULL.
Result
More predictable query results without NULL interference.
Knowing how NULL affects IN prevents subtle bugs in filtering logic.
7
ExpertPerformance Considerations of IN Subqueries
🤔Before reading on: do you think IN subqueries always perform well, or can they cause slow queries? Commit to your answer.
Concept: IN subqueries can be slow if not optimized; understanding execution helps write efficient queries.
Databases may execute IN subqueries by running the inner query once or multiple times. Large subquery results or missing indexes can slow queries. Sometimes rewriting as JOIN or EXISTS improves speed. Analyzing query plans helps decide the best approach.
Result
Better performing queries and understanding when to rewrite IN subqueries.
Knowing the internal execution of IN subqueries helps avoid performance pitfalls in real systems.
Under the Hood
When a query with IN and a subquery runs, the database first executes the subquery to get a list of values. Then, for each row in the outer query, it checks if the column's value is in that list. Depending on the database engine, this list may be stored in memory or optimized with indexes. NULL values in the list require special handling because they represent unknowns, affecting comparison logic.
Why designed this way?
The IN operator with subqueries was designed to simplify filtering by multiple values without manually listing them. It allows dynamic filtering based on related data. Alternatives like multiple OR conditions were verbose and error-prone. The design balances expressiveness and readability, though it requires careful optimization for performance.
┌───────────────┐
│ Outer Query   │
│ SELECT ...    │
│ WHERE col IN ─┼─────────────┐
└───────────────┘             │
                              ▼
                     ┌─────────────────┐
                     │ Subquery        │
                     │ SELECT values    │
                     └─────────────────┘
                              │
                              ▼
                    ┌───────────────────┐
                    │ List of values     │
                    └───────────────────┘
                              │
                              ▼
                Outer query checks if col is in list
Myth Busters - 4 Common Misconceptions
Quick: Does WHERE col IN (subquery) always return rows if the subquery returns NULL? Commit yes or no.
Common Belief:If the subquery returns NULL, the IN condition still matches rows as if NULL was a value.
Tap to reveal reality
Reality:If the subquery returns NULL, the IN condition may not match any rows because NULL means unknown, not a value.
Why it matters:Assuming NULL behaves like a value can cause missing results and incorrect data filtering.
Quick: Is WHERE col IN (subquery) always faster than JOINs? Commit yes or no.
Common Belief:IN with subqueries is always faster and better than JOINs.
Tap to reveal reality
Reality:IN subqueries can be slower than JOINs depending on data size and indexes; sometimes JOINs or EXISTS perform better.
Why it matters:Blindly using IN can cause slow queries and poor application performance.
Quick: Does IN operator only work with subqueries? Commit yes or no.
Common Belief:IN only works with subqueries and cannot use a fixed list of values.
Tap to reveal reality
Reality:IN works with both fixed lists (e.g., IN (1,2,3)) and subqueries returning lists.
Why it matters:Not knowing this limits query writing flexibility and leads to unnecessarily complex queries.
Quick: Does the subquery in IN run once or multiple times? Commit your guess.
Common Belief:The subquery runs once and its result is reused for all rows in the outer query.
Tap to reveal reality
Reality:Depending on the database engine and query, the subquery may run multiple times, affecting performance.
Why it matters:Misunderstanding execution can lead to unexpected slow queries and inefficient designs.
Expert Zone
1
Some databases optimize IN subqueries by transforming them into semi-joins internally for better performance.
2
The presence of NULLs in subquery results can cause three-valued logic issues, requiring explicit NULL filtering.
3
Using IN with correlated subqueries can cause the subquery to execute repeatedly, drastically affecting performance.
When NOT to use
Avoid IN subqueries when dealing with very large datasets or correlated subqueries that run repeatedly. Instead, use JOINs, EXISTS, or temporary tables for better performance and clarity.
Production Patterns
In production, IN subqueries are often used for filtering based on user permissions, category memberships, or dynamic lists. Experts monitor query plans and rewrite queries to JOINs or EXISTS when performance issues arise.
Connections
Set Theory
IN operator corresponds to checking membership in a set.
Understanding IN as set membership helps grasp filtering logic and the importance of unique values.
Functional Programming - Filter Functions
IN with subqueries acts like filtering a list based on membership in another list.
Knowing filter patterns in programming clarifies how databases filter rows using subqueries.
Access Control Lists (ACL) in Security
IN operator filters data based on allowed values, similar to how ACLs check permissions.
Recognizing this connection helps understand practical uses of IN for permission-based data access.
Common Pitfalls
#1Including NULL values in the subquery without filtering.
Wrong approach:SELECT name FROM employees WHERE department_id IN (SELECT id FROM departments); -- departments.id may contain NULL
Correct approach:SELECT name FROM employees WHERE department_id IN (SELECT id FROM departments WHERE id IS NOT NULL);
Root cause:Not realizing NULLs cause unknown comparisons that exclude rows unexpectedly.
#2Using IN subquery on large tables without indexes.
Wrong approach:SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE city = 'New York'); -- no index on customers.city
Correct approach:CREATE INDEX idx_customers_city ON customers(city); SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE city = 'New York');
Root cause:Ignoring the need for indexes leads to slow subquery execution and poor performance.
#3Confusing IN with equality for multiple values.
Wrong approach:SELECT * FROM products WHERE category_id = (SELECT id FROM categories WHERE name = 'Books' OR name = 'Magazines');
Correct approach:SELECT * FROM products WHERE category_id IN (SELECT id FROM categories WHERE name = 'Books' OR name = 'Magazines');
Root cause:Using = with subqueries returning multiple rows causes errors; IN is needed for multiple values.
Key Takeaways
The IN operator with subqueries lets you filter rows by checking if a value exists in a dynamic list returned by another query.
Subqueries inside IN run first, producing a list that the outer query uses to match values efficiently and clearly.
NULL values in subquery results can cause unexpected filtering behavior, so always handle or exclude NULLs explicitly.
IN subqueries simplify complex OR conditions but may have performance trade-offs; understanding execution helps optimize queries.
Knowing when to use IN, JOIN, or EXISTS is key to writing fast, maintainable database queries in real-world applications.

Practice

(1/5)
1. What does the IN operator do when used with a subquery in SQL?
easy
A. It checks if a value matches any value returned by the subquery.
B. It updates values in the main query based on the subquery.
C. It deletes rows that are returned by the subquery.
D. It creates a new table from the subquery results.

Solution

  1. Step 1: Understand the role of IN operator

    The IN operator compares a value to a list of values and returns true if it matches any of them.
  2. Step 2: Understand subquery usage

    The subquery returns a list of values that the main query uses to filter rows with the IN operator.
  3. Final Answer:

    It checks if a value matches any value returned by the subquery. -> Option A
  4. Quick Check:

    IN with subquery = match any value [OK]
Hint: IN checks if value is inside subquery result list [OK]
Common Mistakes:
  • Thinking IN updates or deletes rows
  • Confusing IN with JOIN
  • Assuming IN creates new tables
2. Which of the following is the correct syntax to use a subquery with the IN operator?
easy
A. SELECT * FROM employees WHERE IN department_id (SELECT id FROM departments);
B. SELECT * FROM employees WHERE department_id = IN (SELECT id FROM departments);
C. SELECT * FROM employees WHERE department_id IN (SELECT id FROM departments);
D. SELECT * FROM employees WHERE department_id IN SELECT id FROM departments;

Solution

  1. Step 1: Review correct IN syntax

    The IN operator must be followed by parentheses enclosing the subquery.
  2. Step 2: Check each option

    SELECT * FROM employees WHERE department_id IN (SELECT id FROM departments); correctly uses IN with parentheses and a subquery. Options A, B, and D have syntax errors.
  3. Final Answer:

    SELECT * FROM employees WHERE department_id IN (SELECT id FROM departments); -> Option C
  4. Quick Check:

    IN syntax = IN (subquery) [OK]
Hint: Use parentheses around subquery after IN [OK]
Common Mistakes:
  • Adding = before IN
  • Missing parentheses around subquery
  • Placing IN before column name
3. Given the tables:
Employees(emp_id, name, dept_id)
Departments(dept_id, dept_name)
What will this query return?
SELECT name FROM Employees WHERE dept_id IN (SELECT dept_id FROM Departments WHERE dept_name = 'Sales');
medium
A. Names of employees who do not work in the Sales department.
B. Names of employees who work in the Sales department.
C. All employee names regardless of department.
D. An error because subquery returns multiple rows.

Solution

  1. Step 1: Understand subquery filtering

    The subquery selects dept_id values where dept_name is 'Sales'.
  2. Step 2: Main query filters employees

    The main query selects employee names whose dept_id matches any dept_id from the subquery.
  3. Final Answer:

    Names of employees who work in the Sales department. -> Option B
  4. Quick Check:

    IN filters employees by Sales dept_id [OK]
Hint: IN filters rows matching subquery values [OK]
Common Mistakes:
  • Thinking it returns employees outside Sales
  • Assuming subquery causes error with multiple rows
  • Ignoring subquery filtering condition
4. Identify the error in this query:
SELECT emp_id FROM Employees WHERE dept_id IN SELECT dept_id FROM Departments;
medium
A. Subquery should be in the FROM clause.
B. Using IN instead of EXISTS.
C. dept_id should be compared with = not IN.
D. Missing parentheses around the subquery after IN.

Solution

  1. Step 1: Check IN operator syntax

    The IN operator requires the subquery to be enclosed in parentheses.
  2. Step 2: Identify missing parentheses

    The query lacks parentheses around the subquery, causing a syntax error.
  3. Final Answer:

    Missing parentheses around the subquery after IN. -> Option D
  4. Quick Check:

    IN needs (subquery) [OK]
Hint: Always put subquery inside parentheses after IN [OK]
Common Mistakes:
  • Omitting parentheses around subquery
  • Confusing IN with EXISTS
  • Using = instead of IN for multiple values
5. You want to find all customers who have placed orders for products in the 'Electronics' category. Given tables:
Customers(customer_id, name)
Orders(order_id, customer_id, product_id)
Products(product_id, category)
Which query correctly uses a subquery with IN to get these customers?
hard
A. SELECT name FROM Customers WHERE customer_id IN (SELECT customer_id FROM Orders WHERE product_id IN (SELECT product_id FROM Products WHERE category = 'Electronics'));
B. SELECT name FROM Customers WHERE customer_id = (SELECT customer_id FROM Orders WHERE product_id IN (SELECT product_id FROM Products WHERE category = 'Electronics'));
C. SELECT name FROM Customers WHERE customer_id IN (SELECT product_id FROM Products WHERE category = 'Electronics');
D. SELECT name FROM Customers WHERE customer_id IN (SELECT order_id FROM Orders WHERE product_id IN (SELECT product_id FROM Products WHERE category = 'Electronics'));

Solution

  1. Step 1: Understand the relationships

    Customers link to Orders by customer_id; Orders link to Products by product_id.
  2. Step 2: Analyze the nested subqueries

    The innermost subquery selects product_ids in 'Electronics'. The middle subquery selects customer_ids from Orders with those product_ids. The outer query selects customer names with those customer_ids.
  3. Final Answer:

    SELECT name FROM Customers WHERE customer_id IN (SELECT customer_id FROM Orders WHERE product_id IN (SELECT product_id FROM Products WHERE category = 'Electronics')); -> Option A
  4. Quick Check:

    Nested IN filters customers by Electronics orders [OK]
Hint: Use nested IN for multi-level filtering [OK]
Common Mistakes:
  • Using = instead of IN for multiple customer_ids
  • Comparing customer_id with product_id or order_id
  • Missing nested subquery for product filtering