While UNION adds sets together, INTERSECT finds what they have in common, and EXCEPT (also known as MINUS) finds what makes them different.
Note: For many years, MySQL did not support these natively. Starting in version 8.0.31, native support was added. We will cover both the native syntax and the "Classic Simulation" for older versions.
INTERSECT: Returns only the rows that appear in both Query A and Query B.EXCEPT(orMINUS): Returns rows from Query A that do not appear in Query B.
INTERSECT: "Find users who are both a Customer and a Supplier."EXCEPT: "Find customers who have registered but have NEVER placed an order." (Excluded rows).
If you are on a MySQL version older than 8.0.31, you must simulate these using Joins or Subqueries. Every professional should know these patterns:
-- Find common IDs
SELECT ID FROM TableA
INNER JOIN TableB USING (ID);
-- OR
SELECT ID FROM TableA WHERE ID IN (SELECT ID FROM TableB);-- Find IDs in A but not in B
SELECT a.ID FROM TableA a
LEFT JOIN TableB b ON a.ID = b.ID
WHERE b.ID IS NULL;
-- OR
SELECT ID FROM TableA WHERE ID NOT IN (SELECT ID FROM TableB);-- Finding common emails
SELECT Email FROM Newsletter_Subscribers
INTERSECT
SELECT Email FROM Customer_List;
-- Finding subscribers who are NOT customers
SELECT Email FROM Newsletter_Subscribers
EXCEPT
SELECT Email FROM Customer_List;Internally, INTERSECT and EXCEPT typically use a Hash Set:
- MySQL builds a Hash Table for the results of the second query.
- It then iterates through the first query.
- For INTERSECT: If the row exists in the hash table, it returns it.
- For EXCEPT: If the row does NOT exist in the hash table, it returns it.
- Assuming EXCEPT is symmetric:
A EXCEPT Bis NOT the same asB EXCEPT A. The first one finds "A without B," the second finds "B without A." - Handling NULLs: In Set Operations,
NULLis treated as a value. Two rows withNULLin the same column are considered "Equal" for anINTERSECTorEXCEPTcheck, unlike in a Join whereNULL = NULLis unknown.
EXCEPT vs. NOT EXISTS:
While EXCEPT is cleaner to read, NOT EXISTS (Topic 11.9) is often faster for complex exclusion logic because it allows the optimizer to "short-circuit" as soon as it finds one match in the second table.
- Task 1: Using the simulation pattern, write a query to find all
Product_IDsthat exist in theInventorytable but NOT in theDaily_Salestable. - Task 2: What is the fundamental difference in how
NULLis handled between aJOINand anINTERSECToperation?