00:00

MySQL NOT

Last updated: 4 min read

The NOT operator reverses a condition: rows that would have matched are excluded, and rows that wouldn't are included. It is used on its own (NOT condition) and inside other operators: NOT IN, NOT LIKE, NOT BETWEEN, NOT EXISTS and IS NOT NULL.

1. How NOT Works

NOT truth tableNOT TRUE is FALSE, NOT FALSE is TRUE, and NOT NULL (unknown) is still NULL.conditionNOT conditionTRUE (1)FALSE (0)FALSE (0)TRUE (1)NULLNULLunknown stays unknown, so NOT never selects NULL rows
Figure 1: NOT flips TRUE and FALSE, but NULL (unknown) stays NULL.

Table: flats (6 rows)

flat_idareabhkrentfurnishedpets_oklisted_on
1Kothrud224000102026-02-01
2Baner338000112026-02-10
3Kothrud1150000NULL2026-02-12
4Hadapsar219000012026-02-20
5Wakad331000NULL02026-03-02
6Baner2270001NULL2026-03-05
query.sql
SELECT NOT TRUE AS not_true, NOT FALSE AS not_false, NOT NULL AS not_null, NOT (2 > 5) AS not_expr;

Result: 1 row

not_truenot_falsenot_nullnot_expr
01NULL1

2. NOT on a Condition

query.sql
SELECT flat_id, area, rent FROM flats WHERE NOT area = 'Baner';

Result: 4 rows

flat_idarearent
1Kothrud24000
3Kothrud15000
4Hadapsar19000
5Wakad31000

Use parentheses to negate a whole group of conditions:

query.sql
SELECT flat_id, area, bhk FROM flats WHERE NOT (area = 'Baner' OR bhk = 1);

Result: 3 rows

flat_idareabhk
1Kothrud2
4Hadapsar2
5Wakad3

3. NOT with Other Operators

query.sql
SELECT flat_id, area FROM flats WHERE area NOT IN ('Baner', 'Wakad');

Result: 3 rows

flat_idarea
1Kothrud
3Kothrud
4Hadapsar
query.sql
SELECT flat_id, rent FROM flats WHERE rent NOT BETWEEN 20000 AND 30000;

Result: 4 rows

flat_idrent
238000
315000
419000
531000
query.sql
SELECT flat_id, area FROM flats WHERE area NOT LIKE '%d';

Result: 3 rows

flat_idarea
2Baner
4Hadapsar
6Baner
query.sql
SELECT flat_id, pets_ok FROM flats WHERE pets_ok IS NOT NULL;

Result: 4 rows

flat_idpets_ok
10
21
41
50

4. NOT with Boolean Columns

For a boolean column you can write NOT furnished. But flat 5's furnished is NULL (unknown), so it appears in neither list:

query.sql
SELECT flat_id FROM flats WHERE furnished;

furnished

flat_id
1
2
6
query.sql
SELECT flat_id FROM flats WHERE NOT furnished;

NOT furnished

flat_id
3
4
query.sql
SELECT flat_id FROM flats WHERE furnished IS NOT TRUE;

IS NOT TRUE also catches NULL

flat_id
3
4
5
IS NOT TRUE is TRUE for FALSE and NULL, which is often what "not furnished" should mean in a report.

5. De Morgan's Laws

Pushing NOT inside parentheses swaps AND and OR:

ExpressionEquivalent
NOT (A AND B)NOT A OR NOT B
NOT (A OR B)NOT A AND NOT B
query.sql
SELECT flat_id FROM flats WHERE NOT (bhk = 2 AND rent < 25000);

Result: 4 rows

flat_id
2
3
5
6
query.sql
SELECT flat_id FROM flats WHERE bhk <> 2 OR rent >= 25000;

Result: 4 rows

flat_id
2
3
5
6

Same rows. The second form is often easier to read and to index.

6. NOT and NULL Together

Since NOT leaves NULL as NULL, "everything that isn't X" silently misses unknowns. Flats where pets aren't allowed:

query.sql
SELECT flat_id, pets_ok FROM flats WHERE NOT pets_ok;

Result: 2 rows

flat_idpets_ok
10
50

Flats 3 and 6 (unknown) are missing. Decide whether unknown should count, and write it explicitly:

query.sql
SELECT flat_id, pets_ok FROM flats WHERE NOT pets_ok OR pets_ok IS NULL;

Result: 4 rows

flat_idpets_ok
10
3NULL
50
6NULL

7. NOT EXISTS

not-exists.sql
CREATE TABLE visits (flat_id INT, visitor VARCHAR(20), visit_date DATE);
INSERT INTO visits VALUES (1,'Ravi','2026-03-01'),(2,'Sneha','2026-03-02'),(2,'Tara','2026-03-03'),(4,'Ravi','2026-03-04');

SELECT f.flat_id, f.area
FROM flats f
WHERE NOT EXISTS (SELECT 1 FROM visits v WHERE v.flat_id = f.flat_id);

Result: 3 rows

flat_idarea
3Kothrud
5Wakad
6Baner

See MySQL EXISTS.

8. The ! Operator

MySQL also accepts ! as a synonym for NOT (deprecated in 8.0 in favour of NOT, and not standard SQL):

query.sql
SELECT !TRUE AS bang_true, NOT TRUE AS not_true;

Result: 1 row

bang_truenot_true
00
Precedence matters: NOT a = b means NOT (a = b), but !a = b means (!a) = b. Prefer NOT and parentheses.

9. Practice Exercises

Exercise 1: Flats that are not 2 BHK and not in Kothrud.
solution.sql
SELECT flat_id, area, bhk FROM flats WHERE NOT (bhk = 2 OR area = 'Kothrud');

Result: 2 rows

flat_idareabhk
2Baner3
5Wakad3
Exercise 2: Flats not listed in February 2026.
solution.sql
SELECT flat_id, listed_on FROM flats WHERE listed_on NOT BETWEEN '2026-02-01' AND '2026-02-28';

Result: 2 rows

flat_idlisted_on
52026-03-02
62026-03-05

10. Summary

  • NOT reverses TRUE and FALSE; NOT NULL is still NULL.
  • Use NOT IN, NOT LIKE, NOT BETWEEN, NOT EXISTS and IS NOT NULL for common cases.
  • Negating conditions skips rows with NULLs; add OR col IS NULL or use IS NOT TRUE when needed.
  • De Morgan: NOT (A AND B) = NOT A OR NOT B; NOT (A OR B) = NOT A AND NOT B.
  • Prefer NOT over the deprecated !.