iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

SQL NOT

NOT negates a condition. Combine with =, IN, EXISTS, BETWEEN, LIKE, NULL for clean exclusion logic.

NOT in practice

EXAMPLE
-- NOT with equality
SELECT id FROM users WHERE NOT country = 'AU';
-- Equivalent and more readable:
SELECT id FROM users WHERE country <> 'AU';

-- NOT IN
SELECT id FROM users
WHERE country NOT IN ('AU', 'NZ', 'US');

-- NOT IN gotcha: a NULL inside the list makes EVERY row not match
SELECT id FROM users WHERE country NOT IN ('AU', NULL);
-- Returns ZERO rows (because anything compared to NULL is unknown)

-- Safer: NOT EXISTS
SELECT u.id
FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM bans b WHERE b.user_id = u.id
);

-- NOT LIKE
SELECT email FROM users WHERE email NOT LIKE '%@spammy.com';

-- NOT BETWEEN
SELECT id FROM orders WHERE total NOT BETWEEN 100 AND 500;

-- IS NOT NULL - the only way to test for non-null
SELECT id FROM users WHERE deleted_at IS NOT NULL;

-- Combining with AND/OR
SELECT id, email
FROM users
WHERE active = TRUE
  AND NOT (country = 'AU' AND tier = 'free');

-- Equivalent via De Morgan's law
SELECT id, email
FROM users
WHERE active = TRUE
  AND (country <> 'AU' OR tier <> 'free');

-- NOT in CHECK constraints
CREATE TABLE orders (
  id    SERIAL PRIMARY KEY,
  total INT NOT NULL CHECK (total >= 0),
  status TEXT NOT NULL CHECK (status IN ('open','paid','shipped','cancelled'))
);

-- NOT EXISTS for anti-joins (users with no orders)
SELECT u.id
FROM users u
WHERE NOT EXISTS (
  SELECT 1 FROM orders o WHERE o.user_id = u.id
);

Why it matters

Most NOT-bugs come from NULL. Use NOT EXISTS instead of NOT IN whenever the inner set might contain NULL. Prefer <> for equality negation - it reads cleaner than NOT =.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
SELECT * FROM customers
WHERE NOT country = 'US';
Try it Yourself »

Exercise

Find rows where the phone is present (not null).

WHERE phone IS NULL

Test yourself

Q1. NOT IS NULL is replaced by…
Q2. NOT IN with a NULL in the list…
Q3. A safer alternative to NOT IN for anti-join is…

Discussion

Loading…