SQL Tutorial › Querying Data › AND, OR, NOT

SQL AND, OR and NOT Operators

BeginnerLesson 10 of 6910 min read7 queries run on MySQL 8.4

A single condition is rarely enough. “Furniture and under 5,000″, “Pune or Delhi”, “not cancelled”: AND, OR and NOT combine conditions in a WHERE clause. The one rule that catches everyone is precedence: AND binds tighter than OR, so you need parentheses more often than you think.

Advertisement
In this lesson
  • Require several conditions with AND
  • Accept any of several conditions with OR
  • Negate a condition with NOT
  • Use parentheses to control precedence, and know how NULL affects logic

Sample data

products · 9 rows
product_idproduct_namecategorypricestock
1Wireless MouseElectronics799120
2Mechanical KeyboardElectronics349945
3USB-C HubElectronics19990
4Office ChairFurniture899912
5Standing DeskFurniture189995
6Notebook PackStationery249300
7Gel PensStationery199250
8Desk LampFurniture149930
9Monitor ArmFurniture279918

AND: every condition must be true

Furniture that costs less than 5,000:

SQL
SELECT product_name, category, priceFROM productsWHERE category = 'Furniture'  AND price < 5000;
ResultMySQL 8.4
product_namecategoryprice
Desk LampFurniture1499
Monitor ArmFurniture2799
2 rows in set
How this query works, step by step
  1. MySQL checks both conditions for each of the 9 products.
  2. A row is kept only when both are true: it is Furniture and its price is below 5,000.
  3. The Office Chair and Standing Desk are Furniture but too expensive, so only the Desk Lamp and Monitor Arm remain.

OR: at least one condition must be true

Employees based in Pune or Delhi:

SQL
SELECT first_name, cityFROM employeesWHERE city = 'Pune'   OR city = 'Delhi';
ResultMySQL 8.4
first_namecity
PriyaPune
KavyaPune
RohanPune
SnehaDelhi
4 rows in set
How this query works, step by step
  1. A row is kept when the city is Pune, or Delhi, or (impossible here) both.
  2. Three employees are in Pune and one in Delhi: 4 rows.
Tip

A list of ORs on the same column is easier to read with IN: WHERE city IN ('Pune', 'Delhi').

NOT: reverse a condition

All orders except the delivered ones:

SQL
SELECT order_id, statusFROM ordersWHERE NOT status = 'Delivered';
ResultMySQL 8.4
order_idstatus
1004Cancelled
1006Shipped
1008Pending
3 rows in set

NOT also combines with other operators: NOT IN, NOT BETWEEN, NOT LIKE, IS NOT NULL.

Precedence: AND before OR

Goal: Electronics or Stationery products that are in stock. This first attempt looks right but is wrong:

SQL
SELECT product_name, category, stockFROM productsWHERE category = 'Electronics'   OR category = 'Stationery'  AND stock > 0;
ResultMySQL 8.4
product_namecategorystock
Wireless MouseElectronics120
Mechanical KeyboardElectronics45
USB-C HubElectronics0
Notebook PackStationery300
Gel PensStationery250
5 rows in set
How this query works, step by step
  1. AND is evaluated before OR, so MySQL reads the condition as category = 'Electronics' OR (category = 'Stationery' AND stock > 0).
  2. Every Electronics product passes, whatever its stock, so the out-of-stock USB-C Hub (stock 0) slips in.

Parentheses say what you mean:

SQL
SELECT product_name, category, stockFROM productsWHERE (category = 'Electronics' OR category = 'Stationery')  AND stock > 0;
ResultMySQL 8.4
product_namecategorystock
Wireless MouseElectronics120
Mechanical KeyboardElectronics45
Notebook PackStationery300
Gel PensStationery250
4 rows in set
How this query works, step by step
  1. The parentheses group the two category tests into one condition.
  2. That group and stock > 0 must both be true.
  3. The USB-C Hub now fails the stock test: 4 rows instead of 5.
Watch out

Whenever a WHERE clause mixes AND and OR, add parentheses, even when the default order happens to be correct. The next person to read the query will thank you.

OrderOperator
1comparisons: =, <, >, LIKE, IN …
2NOT
3AND
4OR

AND, OR and NULL

SQL uses three-valued logic: a condition can be TRUE, FALSE or UNKNOWN (when NULL is involved). WHERE keeps only TRUE rows.

SQL
SELECT first_name, commissionFROM employeesWHERE commission > 5000 OR commission < 5000;
ResultMySQL 8.4
first_namecommission
Vikram12000
Neha6000
Arjun4500
3 rows in set
How this query works, step by step
  1. For the three sales staff, commission has a value, so one of the two comparisons is true: Vikram (12,000), Neha (6,000), Arjun (4,500).
  2. For the other nine employees commission is NULL. NULL > 5000 is UNKNOWN, and so is NULL < 5000.
  3. UNKNOWN OR UNKNOWN is still UNKNOWN, so those rows are dropped.
ABA AND BA OR B
TRUEUNKNOWNUNKNOWNTRUE
FALSEUNKNOWNFALSEUNKNOWN
UNKNOWNUNKNOWNUNKNOWNUNKNOWN

A realistic filter

Engineering or Sales employees hired before 2022 who earn at least 90,000:

SQL
SELECT first_name, dept_id, hire_date, salaryFROM employeesWHERE (dept_id = 1 OR dept_id = 2)  AND hire_date < '2022-01-01'  AND salary >= 90000ORDER BY salary DESC;
ResultMySQL 8.4
first_namedept_idhire_datesalary
Asha12018-04-12125000
Vikram22017-11-20105000
Rahul12019-07-0198000
3 rows in set
How this query works, step by step
  1. The parentheses keep departments 1 and 2.
  2. hire_date < '2022-01-01' removes recent hires.
  3. salary >= 90000 removes the lower salaries.
  4. Asha, Vikram and Rahul pass all three tests.

Exercise: Cheap or plentiful

List products that cost less than 500 or have more than 100 in stock. Show product_name, price and stock.

Expected resultMySQL 8.4
product_namepricestock
Wireless Mouse799120
Notebook Pack249300
Gel Pens199250
3 rows in set
Hint 1

Two conditions joined by OR.

Exercise: Delivered in the first quarter

List delivered orders placed in January, February or March 2025 (order_date from 2025-01-01 to 2025-03-31).

Expected resultMySQL 8.4
order_idorder_datestatus
10012025-01-05Delivered
10022025-01-17Delivered
10032025-02-02Delivered
10052025-03-08Delivered
4 rows in set
Hint 1

Three conditions: the status, the first date and the last date, joined with AND.

Quick quiz

1. Which is evaluated first?

2. WHERE a = 1 OR b = 2 AND c = 3 is the same as…

3. What is TRUE OR UNKNOWN?

4. Why does WHERE commission > 5000 OR commission < 5000 skip employees with a NULL commission?

AND / OR FAQ

What is the difference between AND and OR in SQL?

AND returns a row only when all conditions are true. OR returns a row when at least one condition is true.

Does AND or OR come first in SQL?

AND is evaluated before OR. Use parentheses to change the order or simply to make it obvious.

Can I use AND and OR in the same WHERE clause?

Yes, as long as you group conditions with parentheses, for example WHERE (city = 'Pune' OR city = 'Delhi') AND salary > 50000.

How does NOT work with NULL?

NOT UNKNOWN is still UNKNOWN, so NOT (commission > 5000) does not return rows where commission is NULL. Test for NULL explicitly with IS NULL.