Logical Operators: AND, OR, NOT
Progress Tracking
Log in to save this lesson and continue from where you left off.
Combining Conditions
A single WHERE condition gets you pretty far, but real questions usually need more:
- Find employees in HR who earn over 80,000
- Show me orders from March or April
- Get everyone except the Admin department
That's where AND, OR, and NOT come in. They let you combine multiple conditions into one filter.
AND: Both Conditions Must Be True
SELECT *
FROM orders
WHERE order_details = 'Coat'
AND total_order_cost > 100;| id | first_name | last_name | department | salary | phone_number | joining_date |
|---|---|---|---|---|---|---|
| 1 | Sarah | Mitchell | HR | 95000 | 555-0101 | 2021-03-15 |
| 2 | Michael | Chen | HR | 88000 | 555-0102 | 2022-06-01 |
| 3 | Emily | Rodriguez | HR | 82500 | 2021-09-20 | |
| 4 | David | Park | HR | 80000 | 555-0104 | 2023-01-10 |
| 5 | Lisa | Thompson | HR | 65000 | 2021-04-05 |
Find HR employees earning over 80000 from `techcorp_workforce`.
Both conditions must be true for a row to be included.
Chaining Multiple ANDs
You can chain as many ANDs as you need. Try adding a third condition — what happens if you also filter for employees who joined after January 1, 2022?
Find Admin employees earning at least 80,000 who joined after January 1, 2022.
Each AND adds another filter, narrowing your results.
Churro Activity Date
| serial_number | activity_date | facility_name | score | grade | service_code | service_description | employee_id | facility_address | facility_city | facility_id | facility_state | facility_zip | owner_id | owner_name | pe_description | program_element_pe | program_name | program_status | record_id |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| DAQHRSETQ | 2017-06-08 | MARGARITAS CAFE | 93 | A | 1 | ROUTINE INSPECTION | EE0000006 | 5026 S CRENSHAW BLVD | LOS ANGELES | FA0023656 | CA | 90043 | OW0004133 | BAZAN, ASCENCION | RESTAURANT (61-150) SEATS HIGH RISK | 1638 | MARGARITAS CAFE | ACTIVE | PR0011718 |
| DA2GQRJOS | 2017-03-07 | LAS MOLENDERAS | 97 | A | 1 | ROUTINE INSPECTION | EE0000997 | 2635 WHITTIER BLVD | LOS ANGELES | FA0160416 | CA | 90023 | OW0125379 | MARISOL FEREGRINO | RESTAURANT (0-30) SEATS HIGH RISK | 1632 | LAS MOLENDERAS | INACTIVE | PR0148504 |
| DAMQTA46T | 2016-03-22 | SANDRA'S TAMALES | 93 | A | 1 | ROUTINE INSPECTION | EE0001049 | 5390 WHITTIER BLVD | LOS ANGELES | FA0171769 | CA | 90022-4032 | OW0178828 | SANDRA'S TAMALES INC. | RESTAURANT (0-30) SEATS MODERATE RISK | 1631 | SANDRA'S TAMALES | ACTIVE | PR0164225 |
| DAXMBTIRZ | 2018-02-12 | CAFE GRATITUDE | 97 | A | 1 | ROUTINE INSPECTION | EE0000828 | 639 N LARCHMONT BLVD STE #102 | LOS ANGELES | FA0058921 | CA | 90004 | OW0005704 | CAFE GRATITUDE LARCHMONT LLC | RESTAURANT (61-150) SEATS HIGH RISK | 1638 | CAFE GRATITUDE | ACTIVE | PR0019854 |
| DAK8TBMS0 | 2015-09-10 | THE WAFFLE | 90 | A | 1 | ROUTINE INSPECTION | EE0000709 | 6255 W SUNSET BLVD STE #105 | LOS ANGELES | FA0051830 | CA | 90028 | OW0035796 | THE WAFFLE, LLC | RESTAURANT (61-150) SEATS HIGH RISK | 1638 | THE WAFFLE | ACTIVE | PR0010922 |
Find the inspection date and risk category (`pe_description`) of facilities named 'STREET CHURROS' that received a score below 95.
SELECT
first_name,
last_name,
department
FROM techcorp_workforce
WHERE department = 'HR'
OR department = 'Admin';A row only needs to match one condition to be included. HR employees are in, Admin employees are in, Engineering employees are out.
When checking the same column for multiple values, IN (covered next lesson) is often cleaner than chaining ORs.
Lyft Driver Wages
| index | start_date | end_date | yearly_salary |
|---|---|---|---|
| 0 | 2018-04-02 | 48303 | |
| 1 | 2018-05-30 | 67973 | |
| 2 | 2015-04-05 | 56685 | |
| 3 | 2015-01-08 | 51320 | |
| 4 | 2017-03-09 | 67507 |
Find all Lyft drivers who earn either equal to or less than 30k USD or equal to or more than 70k USD. Output all details related to retrieved records.
NOT: Exclude Matches
NOT reverses a condition. It gives you everything that doesn't match.
SELECT
first_name,
last_name,
department
FROM techcorp_workforce
WHERE NOT department = 'Admin';This is equivalent to:
WHERE department <> 'Admin'Both work. Use whichever reads more naturally for your situation.
NOT is more powerful when combined with other operators. For example: WHERE NOT department IN ('Admin', 'HR')
Try It
Find all employees who are not in the HR department. Try it using NOT first, then rewrite using <>.
Combining AND and OR
This is where things get tricky. When you mix AND and OR, SQL evaluates AND first. This can lead to unexpected results.
Let's say you want employees in HR or Engineering, but only those earning over 80,000. You might write:
-- This doesn't do what you think!
SELECT
first_name,
department,
salary
FROM techcorp_workforce
WHERE department = 'HR'
OR department = 'Engineering'
AND salary > 80000;Because AND is evaluated first, SQL reads this as:
WHERE department = 'HR'
OR (department = 'Engineering' AND salary > 80000)So you get ALL HR employees (regardless of salary) plus Engineering employees earning over 80,000. Not what you wanted.
Use Parentheses to Control Order
Find employees in HR or Engineering who earn more than 80,000. Use parentheses to make sure the salary filter applies to both departments.
The corrected version groups the OR conditions first, then applies the salary filter.
Parentheses make your intent clear and prevent bugs. Even if they're not strictly necessary, they help whoever reads your code next — including future you.
High Earners in Support Departments
| id | first_name | last_name | department | salary | phone_number | joining_date |
|---|---|---|---|---|---|---|
| 1 | Sarah | Mitchell | HR | 95000 | 555-0101 | 2021-03-15 |
| 2 | Michael | Chen | HR | 88000 | 555-0102 | 2022-06-01 |
| 3 | Emily | Rodriguez | HR | 82500 | 2021-09-20 | |
| 4 | David | Park | HR | 80000 | 555-0104 | 2023-01-10 |
| 5 | Lisa | Thompson | HR | 65000 | 2021-04-05 |
The HR team is reviewing compensation packages for employees in support functions. They want to identify high earners in the HR and Admin departments for a salary benchmarking study. Find all employees who earn more than $80,000 and work in either the HR or Admin department. Return `first name`, `last name`, `department`, and `salary`.
Key Takeaways
ANDrequires all conditions to be true.ORrequires at least one condition to be true.NOTexcludes rows that match the condition.ANDis evaluated beforeOR— use parentheses to override.- When mixing
ANDandOR, always use parentheses to be safe.
What's Next
Chaining ORs for the same column gets tedious. Writing department = 'HR' OR department = 'Account' OR department = 'Admin' is painful. In the next lesson, you'll learn cleaner ways to filter: LIKE for pattern matching, IN for multiple values, and BETWEEN for ranges.