Bird
Raised Fist0
MySQLquery~15 mins

INTERSECT equivalent in MySQL - Deep Dive

Choose your learning style10 modes available
Overview - INTERSECT equivalent
What is it?
INTERSECT is a SQL operation that returns only the rows common to two query results. MySQL does not have a built-in INTERSECT keyword, so we use other methods to find common rows between two tables or queries. This topic explains how to achieve the same result in MySQL using alternative SQL techniques.
Why it matters
Finding common data between two sets is a common task in databases, such as matching customers who bought two different products. Without INTERSECT, MySQL users need a reliable way to get these common rows. Without this concept, users might write inefficient or incorrect queries, leading to wrong data or slow performance.
Where it fits
Before this, learners should understand basic SELECT queries, JOINs, and WHERE clauses. After mastering INTERSECT equivalents, learners can explore advanced set operations, query optimization, and database-specific features.
Mental Model
Core Idea
INTERSECT returns only the rows that appear in both query results, like finding the overlap between two lists.
Think of it like...
Imagine two friends each have a list of favorite movies. INTERSECT is like finding the movies both friends like, the shared favorites.
┌─────────────┐   ┌─────────────┐
│  Query A    │   │  Query B    │
│ {rows set} │   │ {rows set} │
└─────┬───────┘   └─────┬───────┘
      │                 │
      │                 │
      └─────┬───────────┘
            │
      ┌─────▼───────┐
      │ INTERSECT   │
      │ Common rows │
      └─────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding Basic SELECT Queries
🤔
Concept: Learn how to retrieve data from a single table using SELECT.
A SELECT query fetches rows from a table. For example, SELECT name FROM customers; returns all customer names.
Result
A list of names from the customers table.
Understanding SELECT is essential because INTERSECT works by comparing results from two SELECT queries.
2
FoundationUsing JOIN to Combine Tables
🤔
Concept: Learn how JOIN combines rows from two tables based on a related column.
JOIN matches rows from two tables where a condition is true. For example, SELECT a.id FROM table1 a JOIN table2 b ON a.id = b.id; returns ids present in both tables.
Result
Rows where the id exists in both table1 and table2.
JOIN is a key tool to find common rows, which is the core of what INTERSECT does.
3
IntermediateSimulating INTERSECT with INNER JOIN
🤔Before reading on: do you think INNER JOIN returns only common rows or all rows from both tables? Commit to your answer.
Concept: Use INNER JOIN to get rows common to both queries by matching all columns.
To simulate INTERSECT, join two queries on all columns. For example: SELECT a.* FROM table1 a INNER JOIN table2 b ON a.col1 = b.col1 AND a.col2 = b.col2; This returns rows present in both tables.
Result
Rows that appear exactly in both table1 and table2.
Knowing that INNER JOIN on all columns mimics INTERSECT helps write correct queries without native support.
4
IntermediateUsing EXISTS for INTERSECT Equivalent
🤔Before reading on: does EXISTS check for presence or count of rows? Commit to your answer.
Concept: Use EXISTS to check if a row from one query exists in another, returning only common rows.
Example: SELECT * FROM table1 a WHERE EXISTS (SELECT 1 FROM table2 b WHERE a.col1 = b.col1 AND a.col2 = b.col2); This returns rows from table1 that also appear in table2.
Result
Rows from table1 that have matching rows in table2.
EXISTS is efficient for checking presence and can simulate INTERSECT without joining all columns explicitly.
5
IntermediateUsing IN with Composite Keys for Intersection
🤔
Concept: Use IN with tuples to find common rows based on multiple columns.
Example: SELECT * FROM table1 WHERE (col1, col2) IN (SELECT col1, col2 FROM table2); This returns rows in table1 that match rows in table2 on both columns.
Result
Rows from table1 that match rows in table2 on specified columns.
Using IN with multiple columns is a concise way to find common rows, similar to INTERSECT.
6
AdvancedHandling NULLs in INTERSECT Equivalents
🤔Before reading on: do you think NULL equals NULL in SQL comparisons? Commit to your answer.
Concept: Understand how NULL values affect equality checks in INTERSECT simulations.
In SQL, NULL is unknown and does not equal NULL. So, rows with NULLs may not match in JOIN or EXISTS. To handle this, use IS NULL checks or COALESCE to treat NULLs as equal. Example: ON (a.col1 = b.col1 OR (a.col1 IS NULL AND b.col1 IS NULL)) This ensures NULLs are treated as equal for intersection.
Result
Correctly matched rows including those with NULL values.
Handling NULLs properly avoids missing common rows and ensures accurate INTERSECT behavior.
7
ExpertPerformance Considerations for INTERSECT Alternatives
🤔Before reading on: do you think JOIN or EXISTS is always faster? Commit to your answer.
Concept: Learn how query plans and indexes affect performance of INTERSECT simulations.
INNER JOIN can be faster if indexes exist on join columns. EXISTS may be better for large datasets with selective filters. Using composite indexes on all columns involved improves speed. Also, DISTINCT may be needed to remove duplicates, affecting performance. Analyze query plans with EXPLAIN to choose the best method.
Result
Optimized queries that run efficiently on large data.
Understanding performance trade-offs helps write scalable INTERSECT equivalents in production.
Under the Hood
MySQL executes INTERSECT equivalents by performing row-by-row comparisons using JOIN or EXISTS conditions. It matches rows based on equality of all specified columns. Internally, indexes speed up lookups. NULL handling requires special logic because NULL is not equal to NULL in SQL. The database engine uses query optimization to choose the best execution plan.
Why designed this way?
MySQL lacks native INTERSECT to keep the engine simpler and faster for common operations. JOIN and EXISTS are more flexible and powerful, covering many use cases beyond simple intersection. This design lets users build custom set operations as needed.
┌───────────────┐       ┌───────────────┐
│   Query A     │       │   Query B     │
│  (Result Set) │       │  (Result Set) │
└───────┬───────┘       └───────┬───────┘
        │                       │
        │                       │
        └────────────┬──────────┘
                     │
             ┌───────▼────────┐
             │  JOIN / EXISTS │
             │  Condition on  │
             │  all columns   │
             └───────┬────────┘
                     │
             ┌───────▼────────┐
             │  Result: Rows  │
             │  common to A & │
             │  B             │
             └────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does INNER JOIN always behave exactly like INTERSECT? Commit yes or no.
Common Belief:INNER JOIN is exactly the same as INTERSECT and always returns the same results.
Tap to reveal reality
Reality:INNER JOIN returns matching rows but can produce duplicates if tables have duplicates, unlike INTERSECT which removes duplicates by default.
Why it matters:Using INNER JOIN without DISTINCT can lead to unexpected duplicate rows, causing wrong data analysis.
Quick: Does NULL equal NULL in SQL comparisons? Commit yes or no.
Common Belief:NULL values are treated as equal, so rows with NULLs match in INTERSECT equivalents.
Tap to reveal reality
Reality:NULL is unknown and does not equal NULL, so rows with NULLs may not match unless special handling is added.
Why it matters:Ignoring NULL behavior causes missing rows in intersection results, leading to incomplete data.
Quick: Is EXISTS always faster than JOIN for INTERSECT? Commit yes or no.
Common Belief:EXISTS is always faster than JOIN for finding common rows.
Tap to reveal reality
Reality:Performance depends on data size, indexes, and query structure; sometimes JOIN is faster, sometimes EXISTS is.
Why it matters:Assuming one method is always best can cause inefficient queries and slow applications.
Quick: Does IN with multiple columns work in all MySQL versions? Commit yes or no.
Common Belief:IN with tuples (multiple columns) is supported and works like INTERSECT in all MySQL versions.
Tap to reveal reality
Reality:Tuple IN syntax is supported only in MySQL 5.7+; older versions do not support it.
Why it matters:Using unsupported syntax causes query errors and breaks applications on older MySQL versions.
Expert Zone
1
Using composite indexes on all columns involved in the intersection dramatically improves query speed but requires careful index design.
2
DISTINCT is often needed after JOIN or EXISTS to mimic INTERSECT's duplicate removal, but it can add overhead and should be used judiciously.
3
NULL handling in intersection queries is subtle; using COALESCE or explicit IS NULL checks ensures correctness but complicates query logic.
When NOT to use
Avoid simulating INTERSECT with JOIN or EXISTS when working with very large datasets without proper indexes, as performance can degrade. Instead, consider using temporary tables with indexed columns or application-level filtering. For complex set operations, consider using a database that supports INTERSECT natively.
Production Patterns
In production, developers often use INNER JOIN with DISTINCT on all columns to simulate INTERSECT. EXISTS is preferred when filtering one table by presence in another. Queries are optimized with composite indexes and analyzed with EXPLAIN. NULL-safe comparisons are added to avoid missing rows. Sometimes, results are cached or precomputed for performance.
Connections
Set Theory
INTERSECT in SQL directly models the intersection operation in set theory.
Understanding set intersection helps grasp why INTERSECT returns only common elements, reinforcing the logic behind SQL queries.
Relational Algebra
INTERSECT is a fundamental operation in relational algebra, the theoretical foundation of SQL.
Knowing relational algebra clarifies how SQL operations like INTERSECT, JOIN, and UNION relate and differ.
Data Filtering in Programming
INTERSECT is similar to filtering lists or arrays in programming languages to find common elements.
Recognizing this similarity helps programmers translate logic between SQL and code, improving cross-domain problem solving.
Common Pitfalls
#1Using INNER JOIN without matching all columns for intersection.
Wrong approach:SELECT a.* FROM table1 a INNER JOIN table2 b ON a.id = b.id;
Correct approach:SELECT a.* FROM table1 a INNER JOIN table2 b ON a.col1 = b.col1 AND a.col2 = b.col2;
Root cause:Assuming matching on a single column is enough to find common rows when full row equality is needed.
#2Ignoring duplicates when simulating INTERSECT.
Wrong approach:SELECT a.* FROM table1 a INNER JOIN table2 b ON a.col1 = b.col1;
Correct approach:SELECT DISTINCT a.* FROM table1 a INNER JOIN table2 b ON a.col1 = b.col1;
Root cause:Not realizing INTERSECT removes duplicates by default, so DISTINCT is needed to mimic it.
#3Not handling NULL values in join conditions.
Wrong approach:SELECT a.* FROM table1 a INNER JOIN table2 b ON a.col1 = b.col1;
Correct approach:SELECT a.* FROM table1 a INNER JOIN table2 b ON (a.col1 = b.col1 OR (a.col1 IS NULL AND b.col1 IS NULL));
Root cause:Misunderstanding that NULL does not equal NULL in SQL, causing missed matches.
Key Takeaways
MySQL does not have a native INTERSECT keyword, but you can simulate it using INNER JOIN, EXISTS, or IN with multiple columns.
To mimic INTERSECT correctly, match all columns of the rows and use DISTINCT to remove duplicates.
NULL values require special handling because SQL treats NULL as unknown, not equal to NULL.
Performance depends on indexes and query structure; analyze and optimize queries for large datasets.
Understanding set theory and relational algebra helps grasp why and how INTERSECT works.

Practice

(1/5)
1. In MySQL, which of the following is the best way to find rows common to two tables table1 and table2 when INTERSECT is not supported?
easy
A. Use SELECT * FROM table1 JOIN table2 ON table1.column = table2.column
B. Use SELECT * FROM table1 UNION SELECT * FROM table2
C. Use SELECT * FROM table1 WHERE column IN (SELECT column FROM table2)
D. Use SELECT * FROM table1 EXCEPT SELECT * FROM table2

Solution

  1. Step 1: Understand INTERSECT purpose

    INTERSECT returns rows common to both queries or tables.
  2. Step 2: Use WHERE ... IN to mimic INTERSECT

    MySQL lacks INTERSECT, but WHERE column IN (subquery) returns rows in table1 that also appear in table2.
  3. Final Answer:

    Use SELECT * FROM table1 WHERE column IN (SELECT column FROM table2) -> Option C
  4. Quick Check:

    INTERSECT equivalent = WHERE ... IN [OK]
Hint: Use WHERE ... IN (subquery) to find common rows [OK]
Common Mistakes:
  • Using UNION returns all unique rows, not common ones
  • JOIN returns combined rows, not just common rows alone
  • EXCEPT is not supported in MySQL and finds differences
2. Which of the following is the correct syntax to find common id values between tableA and tableB in MySQL?
easy
A. SELECT id FROM tableA INTERSECT SELECT id FROM tableB;
B. SELECT id FROM tableA WHERE id IN (SELECT id FROM tableB);
C. SELECT id FROM tableA UNION SELECT id FROM tableB;
D. SELECT id FROM tableA EXCEPT SELECT id FROM tableB;

Solution

  1. Step 1: Recognize MySQL lacks INTERSECT and EXCEPT

    MySQL does not support INTERSECT or EXCEPT keywords.
  2. Step 2: Use WHERE ... IN syntax for intersection

    The correct syntax is SELECT id FROM tableA WHERE id IN (SELECT id FROM tableB); to get common ids.
  3. Final Answer:

    SELECT id FROM tableA WHERE id IN (SELECT id FROM tableB); -> Option B
  4. Quick Check:

    Correct syntax for INTERSECT equivalent = WHERE ... IN [OK]
Hint: Use WHERE ... IN (subquery) syntax, not INTERSECT [OK]
Common Mistakes:
  • Trying to use INTERSECT or EXCEPT directly in MySQL
  • Using UNION which combines all unique rows
  • Confusing JOIN with intersection
3. Given these tables:
table1:
id
1
2
3

table2:
id
2
3
4

What is the output of this query?
SELECT id FROM table1 WHERE id IN (SELECT id FROM table2);
medium
A. [1, 2, 3]
B. [] (empty set)
C. [4]
D. [2, 3]

Solution

  1. Step 1: Identify ids in table1

    table1 has ids 1, 2, 3.
  2. Step 2: Identify ids in table2

    table2 has ids 2, 3, 4.
  3. Step 3: Find common ids using WHERE ... IN

    The query returns ids from table1 that are also in table2: 2 and 3.
  4. Final Answer:

    [2, 3] -> Option D
  5. Quick Check:

    Common ids = [2, 3] [OK]
Hint: Check which ids appear in both tables [OK]
Common Mistakes:
  • Including ids only in one table (like 1 or 4)
  • Confusing UNION with intersection
  • Expecting all ids from table1
4. You wrote this query to find common user_id values:
SELECT user_id FROM users WHERE user_id IN (SELECT user_id FROM orders);

But it returns an error. What is the most likely cause?
medium
A. The subquery returns multiple columns instead of one
B. The IN clause is not supported in MySQL
C. The user_id column does not exist in orders
D. You need to use INTERSECT instead of IN

Solution

  1. Step 1: Check subquery column count

    The subquery inside IN must return exactly one column.
  2. Step 2: Identify error cause

    If the subquery returns multiple columns, MySQL throws an error.
  3. Final Answer:

    The subquery returns multiple columns instead of one -> Option A
  4. Quick Check:

    Subquery must return single column [OK]
Hint: Ensure subquery returns only one column for IN clause [OK]
Common Mistakes:
  • Using multiple columns in subquery for IN
  • Assuming INTERSECT exists in MySQL
  • Ignoring column existence in tables
5. You want to find all product_id values that appear in both sales and returns tables. Both tables have product_id and date columns. You only want products sold and returned on the same date. Which query correctly finds this intersection?
hard
A. SELECT product_id FROM sales WHERE (product_id, date) IN (SELECT product_id, date FROM returns);
B. SELECT product_id FROM sales WHERE product_id IN (SELECT product_id FROM returns);
C. SELECT product_id FROM sales JOIN returns ON sales.product_id = returns.product_id AND sales.date = returns.date;
D. SELECT product_id FROM sales INTERSECT SELECT product_id FROM returns WHERE sales.date = returns.date;

Solution

  1. Step 1: Understand requirement for matching product_id and date

    We need products sold and returned on the same date, so both columns must match.
  2. Step 2: Use tuple comparison in WHERE ... IN

    MySQL supports tuple comparisons like (product_id, date) IN (SELECT product_id, date FROM returns) to find exact matches.
  3. Step 3: Evaluate other options

    SELECT product_id FROM sales WHERE product_id IN (SELECT product_id FROM returns); ignores date, SELECT product_id FROM sales JOIN returns ON sales.product_id = returns.product_id AND sales.date = returns.date; can produce duplicate product_id values if multiple returns match the same product and date, SELECT product_id FROM sales INTERSECT SELECT product_id FROM returns WHERE sales.date = returns.date; uses unsupported INTERSECT with conditions.
  4. Final Answer:

    SELECT product_id FROM sales WHERE (product_id, date) IN (SELECT product_id, date FROM returns); -> Option A
  5. Quick Check:

    Tuple IN matches multiple columns [OK]
Hint: Use tuple IN (subquery) for multiple column intersection [OK]
Common Mistakes:
  • Ignoring date column in intersection
  • Using INTERSECT which MySQL lacks
  • Using JOIN which can produce duplicate product_ids
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard