SQL Tutorial › Joins & Set Operators › INTERSECT & EXCEPT

SQL INTERSECT and EXCEPT

IntermediateLesson 39 of 698 min read6 queries run on MySQL 8.4

UNION combines two results. Its siblings compare them: INTERSECT returns the rows that appear in both results, and EXCEPT returns rows in the first result that are not in the second. MySQL added both in version 8.0.31, so MySQL 8.4 supports them; older versions need a join or EXISTS.

Advertisement
In this lesson
  • Find common rows with INTERSECT
  • Find missing rows with EXCEPT
  • Understand the duplicate rules
  • Rewrite them with EXISTS for older databases

The two lists

Cities of employees and of customers:

employees · 12 rows (some columns)
emp_idfirst_namecity
100MeeraMumbai
101AshaBengaluru
102RahulBengaluru
103PriyaPune
104KaranBengaluru
105VikramMumbai
106NehaMumbai
107ArjunKolkata
108KavyaPune
109RohanPune
110SnehaDelhi
111AmitBengaluru
customers · 7 rows (some columns)
customer_idcustomer_namecity
1Ananya SharmaMumbai
2Rohit KumarDelhi
3Fatima KhanHyderabad
4David FernandesGoa
5Ishita BoseKolkata
6Manoj PillaiChennai
7Sara ThomasBengaluru

INTERSECT: rows in both

Cities where we have both an employee and a customer:

SQL
SELECT city FROM employeesINTERSECTSELECT city FROM customersORDER BY city;
ResultMySQL 8.4
city
Bengaluru
Delhi
Kolkata
Mumbai
4 rows in set
How this query works, step by step
  1. The first query lists employee cities; the second, customer cities.
  2. INTERSECT keeps the cities that appear in both lists.
  3. Like UNION, it removes duplicates: Bengaluru, Delhi, Kolkata and Mumbai.

EXCEPT: rows in the first only

Cities with employees but no customers:

SQL
SELECT city FROM employeesEXCEPTSELECT city FROM customersORDER BY city;
ResultMySQL 8.4
city
Pune
1 row in set

The order matters. Cities with customers but no employees:

SQL
SELECT city FROM customersEXCEPTSELECT city FROM employeesORDER BY city;
ResultMySQL 8.4
city
Chennai
Goa
Hyderabad
3 rows in set
How this query works, step by step
  1. A EXCEPT B keeps the rows of A that do not appear in B.
  2. Swapping the queries asks the opposite question: Chennai, Goa and Hyderabad have customers but no staff.

Practical example: products never ordered

SQL
SELECT product_id FROM productsEXCEPTSELECT product_id FROM order_items;
ResultMySQL 8.4
product_id
9
1 row in set

Several columns

The comparison uses the whole row, so all selected columns must match. Customer ids that ordered in both January and April 2025:

SQL
SELECT customer_id FROM orders WHERE order_date BETWEEN '2025-01-01' AND '2025-01-31'INTERSECTSELECT customer_id FROM orders WHERE order_date BETWEEN '2025-04-01' AND '2025-04-30';
ResultMySQL 8.4
customer_id
1
2
2 rows in set

Alternatives with EXISTS

On MySQL before 8.0.31 (and many interview answers), write INTERSECT with EXISTS and EXCEPT with NOT EXISTS:

SQL
SELECT DISTINCT e.cityFROM employees eWHERE NOT EXISTS (SELECT 1 FROM customers c WHERE c.city = e.city)ORDER BY e.city;
ResultMySQL 8.4
city
Pune
1 row in set
How this query works, step by step
  1. For each employee city, the subquery checks whether any customer has the same city.
  2. NOT EXISTS keeps the cities with no such customer: the same answer as EXCEPT.
  3. DISTINCT removes repeats, which EXCEPT does automatically. See EXISTS.
Note

INTERSECT ALL and EXCEPT ALL keep duplicates (MySQL supports them too). Also note that, unlike = in WHERE, these operators treat two NULLs as equal.

Quick quiz

1. Which operator returns rows found in both queries?

2. Is A EXCEPT B the same as B EXCEPT A?

3. From which MySQL version are INTERSECT and EXCEPT supported?

INTERSECT and EXCEPT FAQ

Does MySQL support INTERSECT?

Yes, since MySQL 8.0.31. In older versions use an inner join or WHERE EXISTS.

What is the difference between EXCEPT and MINUS?

They do the same thing. Oracle calls it MINUS; standard SQL, PostgreSQL, SQL Server and MySQL use EXCEPT.

What is the difference between INTERSECT and INNER JOIN?

INTERSECT compares whole result rows and removes duplicates. An inner join combines columns of two tables on a condition and can multiply rows.