EXCEPT & INTERSECT
EXCEPT returns rows in the first query but not the second; INTERSECT returns rows common to both.
"Who is a pure batter (bats but doesn't bowl)?" and "Who are the all-rounders (in both lists)?" These are difference and overlap questions — exactly what EXCEPT and INTERSECT answer.
Definitions
EXCEPT (called MINUS in Oracle) returns the distinct rows of the first query that do not appear in the second query.
INTERSECT returns the distinct rows that appear in both queries.
- EXCEPT — Venn: the left circle minus the overlap. Order matters:
A EXCEPT B≠B EXCEPT A. - INTERSECT — Venn: only the overlap. Order does not matter.
- Both compare whole rows (all selected columns) and both return distinct rows.
Example — EXCEPT: in batters but NOT in bowlers
sql
SELECT name, team FROM batters
EXCEPT
SELECT name, team FROM bowlers;| name | team |
|---|---|
| MS Dhoni | CSK |
| Rohit Sharma | MI |
| Virat Kohli | RCB |
How it works: take the 5 batters, remove every row that also appears in bowlers (Jadeja, Pandya) → 3 pure batters.
Example — order matters: bowlers EXCEPT batters
sql
SELECT name, team FROM bowlers
EXCEPT
SELECT name, team FROM batters;| name | team |
|---|---|
| Jasprit Bumrah | MI |
| Rashid Khan | GT |
| Yuzvendra Chahal | PBKS |
Same tables, swapped order, completely different answer: now we get the pure bowlers.
Example — INTERSECT: rows common to both (all-rounders)
sql
SELECT name, team FROM batters
INTERSECT
SELECT name, team FROM bowlers;| name | team |
|---|---|
| Hardik Pandya | MI |
| Ravindra Jadeja | CSK |
Whole-row comparison — a subtle trap
Imagine a bowler row ('Hardik Pandya', 'GT') is added (he played for GT earlier). Then:
| Query | Hardik Pandya in result? |
|---|---|
SELECT name, team … INTERSECT … | yes — the (Hardik Pandya, MI) row is in both |
SELECT name, team FROM bowlers EXCEPT SELECT name, team FROM batters | yes, as (Hardik Pandya, GT) — that exact row isn't in batters |
SELECT name FROM bowlers EXCEPT SELECT name FROM batters | no — compared on name only |
Choose your columns carefully: the more columns you select, the stricter the comparison.
SET operators at a glance
| Operator | Result | On batters / bowlers (names) |
|---|---|---|
| UNION | all rows, duplicates removed | 8 names |
| UNION ALL | all rows, duplicates kept | 10 names |
| EXCEPT / MINUS | unique rows in 1st set not in 2nd | 3 names (pure batters) |
| INTERSECT | only rows common to both | 2 names (all-rounders) |
EXCEPT / INTERSECT vs JOINs
| Set version | Join version |
|---|---|
A INTERSECT B | A INNER JOIN B ON every column matches (+ DISTINCT) |
A EXCEPT B | A LEFT JOIN B ON every column matches WHERE b.key IS NULL (+ DISTINCT) |
Set operators are shorter and treat NULLs as equal; joins are more flexible (you can show columns from both tables).
Common mistakes
- ❌ Assuming
A EXCEPT B=B EXCEPT A. ✅ EXCEPT is directional; always ask "rows of which query?". - ❌ Expecting duplicates from EXCEPT / INTERSECT. ✅ They always return distinct rows (SQL Server has no EXCEPT ALL / INTERSECT ALL).
- ❌ Mixing operators without brackets. ✅ In SQL Server INTERSECT is evaluated before UNION and EXCEPT; use parentheses to make your intent clear.
SQL Server vs other databases
SQL Server and PostgreSQL use EXCEPT; Oracle uses MINUS. MySQL supports EXCEPT and INTERSECT only from 8.0.31. PostgreSQL additionally supports EXCEPT ALL / INTERSECT ALL; SQL Server does not.
Interview tip
Q: Find players who are batters but not bowlers — two ways.
A: SELECT name FROM batters EXCEPT SELECT name FROM bowlers; or SELECT b.name FROM batters b WHERE NOT EXISTS (SELECT 1 FROM bowlers w WHERE w.name = b.name);
Key points to remember
- EXCEPT returns distinct rows of the first query that are not in the second; Oracle calls it MINUS.
- INTERSECT returns distinct rows present in both queries.
- EXCEPT is directional — A EXCEPT B differs from B EXCEPT A; INTERSECT order does not matter.
- Both compare entire rows across all selected columns.
- Both always return distinct rows (no EXCEPT ALL / INTERSECT ALL in SQL Server).
- In SQL Server, INTERSECT has higher precedence than UNION and EXCEPT — use parentheses.
Try it yourself
EXCEPT: pure batters
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
EXCEPT the other way round: pure bowlers
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
INTERSECT: all-rounders
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Practice: whole-row comparison
This example runs a small setup step first — click to see it
INSERT INTO bowlers (name, team) VALUES ('Hardik Pandya', 'GT');Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Revision Flashcards
Tap a card to flip it and see the answer.
