IN & NOT IN (Membership)
Match any value in a list with IN, exclude a list with NOT IN, and avoid the NOT IN + NULL trap.
"Show players from MI or CSK." With OR you'd write team = 'MI' OR team = 'CSK' — fine for two teams, painful for ten. IN lets you give a list instead.
Definition
IN tests whether a value matches any value in a list (or in the result of a subquery).
expr IN (v1, v2, v3)is shorthand forexpr = v1 OR expr = v2 OR expr = v3.NOT IN tests that a value matches none of the list values:
expr NOT IN (v1, v2)meansexpr <> v1 AND expr <> v2.
The "shorthand" is the key: IN is a chain of = joined by OR, and NOT IN is a chain of <> joined by AND. That second fact explains the NULL trap below.
Syntax
sql
SELECT column_list
FROM table_name
WHERE column_name IN (value1, value2, ...);
SELECT column_list
FROM table_name
WHERE column_name NOT IN (value1, value2, ...);
-- the list can also come from a subquery (one column)
WHERE column_name IN (SELECT column_name FROM other_table WHERE ...);| Part | Meaning |
|---|---|
IN | TRUE if the value equals any list item |
NOT IN | TRUE if the value equals no list item |
( ... ) | list in brackets, comma-separated; text values in single quotes |
Example — IN: teams MI or CSK
sql
SELECT *
FROM players
WHERE team IN ('MI', 'CSK');| id | name | team | country | runs |
|---|---|---|---|---|
| 2 | Rohit Sharma | MI | India | 500 |
| 4 | MS Dhoni | CSK | India | 350 |
| 6 | Jasprit Bumrah | MI | India | 20 |
IN is a short way to write team = 'MI' OR team = 'CSK'.
Example — NOT IN: everyone else
sql
SELECT *
FROM players
WHERE team NOT IN ('MI', 'CSK');| id | name | team | country | runs |
|---|---|---|---|---|
| 1 | Virat Kohli | RCB | India | 750 |
| 3 | Jos Buttler | RR | England | 850 |
| 5 | David Warner | DC | Australia | 700 |
NOT IN keeps everything that is not in the list.
Example — IN with a subquery
Players whose team is based in Mumbai or Chennai (the list is built from the teams table):
sql
SELECT name, team
FROM players
WHERE team IN (SELECT team FROM teams WHERE city IN ('Mumbai', 'Chennai'));| name | team |
|---|---|
| Rohit Sharma | MI |
| MS Dhoni | CSK |
| Jasprit Bumrah | MI |
⚠️ The NOT IN + NULL trap
Which franchises have no entry in player_profiles? One player there (David Warner) has team = NULL.
sql
SELECT team, team_name
FROM teams
WHERE team NOT IN (SELECT team FROM player_profiles);Result: 0 rows! Why? The subquery returns ('RCB', 'MI', 'RR', 'CSK', NULL, 'MI'). For KKR, NOT IN expands to 'KKR' <> 'RCB' AND ... AND 'KKR' <> NULL. The last test is UNKNOWN, and TRUE AND UNKNOWN = UNKNOWN → every row is dropped. One NULL in a NOT IN list wipes out the whole result.
✅ Fix — remove NULLs from the list:
sql
SELECT team, team_name
FROM teams
WHERE team NOT IN (SELECT team FROM player_profiles WHERE team IS NOT NULL);| team | team_name |
|---|---|
| DC | Delhi Capitals |
| KKR | Kolkata Knight Riders |
| GT | Gujarat Titans |
(NOT EXISTS is another safe alternative — covered with subqueries.)
Note:
INis not affected the same way:team IN ('MI', NULL)still returns the MI rows, becauseTRUE OR UNKNOWN= TRUE. Also, a row whose own value is NULL never matches IN or NOT IN.
Common mistakes
- ❌
WHERE team IN 'MI', 'CSK'→ brackets required. ✅IN ('MI', 'CSK') - ❌
WHERE team IN ('MI, CSK')→ that is ONE string'MI, CSK'. ✅ quote each value separately. - ❌
NOT IN (subquery)when the subquery column can be NULL → 0 rows. ✅ addWHERE col IS NOT NULLor useNOT EXISTS. - ❌
WHERE team IN (NULL)to find NULLs → never matches. ✅team IS NULL.
Interview tip
Q: Why can NOT IN return no rows even though matches clearly exist?
A: If the list or subquery contains a NULL, x NOT IN (...) becomes ... AND x <> NULL, which is UNKNOWN for every row. Filter NULLs out of the subquery or use NOT EXISTS.
Key points to remember
- IN (a, b, c) is shorthand for = a OR = b OR = c — TRUE if the value matches any item.
- NOT IN (a, b) means <> a AND <> b — TRUE only if the value matches none.
- The list goes inside brackets, comma-separated, each text value in its own quotes.
- The list can come from a one-column subquery: IN (SELECT col FROM ...).
- If a NOT IN list contains NULL, the whole result becomes empty.
- Fix the trap with WHERE col IS NOT NULL inside the subquery, or use NOT EXISTS.
- IN / NOT IN never match a row whose own value is NULL — use IS NULL for that.
Try it yourself
IN: MI or CSK
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
NOT IN: everyone else
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
The NOT IN + NULL trap (and the fix)
Runs on a fresh IPL practice database in your browser · edit the query and press Ctrl + Enter
Practice: overseas countries
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.
