Операторы сравнения и логические операторы (AND, OR, NOT)
Операторы сравнения и логические операторы (AND, OR, NOT)
В предыдущем уроке вы научились фильтровать строки с помощью WHERE и одного условия. Это хороший старт, но реальные задачи редко формулируются так просто. Вам нужны сотрудники из отдела разработки и с зарплатой выше 90000. Или товары ценой до 5000 рублей или со скидкой. Для таких составных условий используются логические операторы: AND, OR и NOT.
AND: оба условия должны быть истинны
AND объединяет два условия. Строка попадает в результат, только если оба условия истинны одновременно.
Синтаксис:
SELECT колонки
FROM таблица
WHERE условие1 AND условие2;
Пример. Получим сотрудников из отдела «Разработка» с зарплатой выше 90000:
SELECT name, department, salary
FROM employees
WHERE department = 'Разработка'
AND salary > 90000;
Для каждой строки база проверяет оба условия. Строка попадёт в результат только если одновременно department = 'Разработка' и salary > 90000. Если хотя бы одно условие ложно — строка отбрасывается.
Таблица employees:
id | name | department | salary
---+--------+--------------+--------
1 | Анна | Разработка | 90000 -- 90000 > 90000 FALSE → не попадает
2 | Борис | Менеджмент | 110000 -- Менеджмент ≠ Разработка → не попадает
3 | Вера | Разработка | 85000 -- 85000 > 90000 FALSE → не попадает
4 | Гриша | Дизайн | 75000 -- Дизайн ≠ Разработка → не попадает
5 | Дина | Разработка | 95000 -- оба условия TRUE → попадает
Результат: только Дина.
AND можно цепочить — добавлять сколько угодно условий:
SELECT name
FROM employees
WHERE department = 'Разработка'
AND salary > 80000
AND salary < 100000;
Это вернёт разработчиков с зарплатой строго между 80000 и 100000.
OR: хотя бы одно условие истинно
OR объединяет условия по принципу «или». Строка попадает в результат, если хотя бы одно из условий истинно.
SELECT name, department
FROM employees
WHERE department = 'Разработка'
OR department = 'Дизайн';
Здесь попадут все сотрудники из «Разработки» или «Дизайна» — оба отдела. Сотрудник попадает, если его department равен хотя бы одному из указанных значений.
Результат для нашей таблицы:
name | department
------+------------
Анна | Разработка
Вера | Разработка
Гриша | Дизайн
Дина | Разработка
Борис (Менеджмент) не попадает — его отдел не совпадает ни с одним из условий.
Проверь себя: сколько строк вернёт WHERE salary < 80000 OR salary > 100000 для нашей таблицы?
NOT: инверсия условия
NOT переворачивает результат условия. Там, где было TRUE, станет FALSE, и наоборот.
SELECT name, department
FROM employees
WHERE NOT department = 'Менеджмент';
Эквивалентно WHERE department <> 'Менеджмент'. Результат — все сотрудники, кроме менеджеров.
NOT чаще используется не как простое отрицание равенства (для этого есть <>), а для инверсии составных условий или специальных операторов:
WHERE NOT (salary < 80000 OR department = 'Дизайн')
WHERE NOT salary BETWEEN 80000 AND 100000 -- BETWEEN разберём позже
WHERE phone IS NOT NULL
Комбинирование AND и OR
Здесь начинается самое интересное. Можно объединять AND и OR в одном условии:
SELECT name, department, salary
FROM employees
WHERE department = 'Разработка' OR department = 'Дизайн'
AND salary > 80000;
Стоп — что означает этот запрос? «Разработчики или дизайнеры с зарплатой выше 80000»? Или «разработчики, или дизайнеры с зарплатой выше 80000»?
Ответ определяет приоритет операторов.
Приоритет: AND выполняется раньше OR
В SQL AND имеет более высокий приоритет, чем OR. Это означает, что запрос выше интерпретируется как:
WHERE department = 'Разработка'
OR (department = 'Дизайн' AND salary > 80000)
То есть: все разработчики (без ограничений по зарплате), плюс дизайнеры с зарплатой выше 80000. Это может быть не тем, что вы хотели.
Если нужно «разработчики или дизайнеры, и те и другие с зарплатой выше 80000», нужны скобки:
WHERE (department = 'Разработка' OR department = 'Дизайн')
AND salary > 80000;
Скобки меняют приоритет, как в математике. Это критически важное правило: при смешивании AND и OR всегда используйте скобки, чтобы не полагаться на приоритет и не получить неожиданный результат.
Скобки: явно всегда лучше
Даже когда вы уверены в приоритете, скобки улучшают читаемость. Сравните:
-- Без скобок (нужно помнить приоритет)
WHERE status = 'active' OR status = 'pending' AND salary > 50000
-- Со скобками (намерение очевидно)
WHERE status = 'active' OR (status = 'pending' AND salary > 50000)
Второй вариант читается однозначно, даже если вы не помните приоритет операторов.
Проверь себя: что вернёт условие WHERE a = 1 OR b = 2 AND c = 3? Как расставить скобки, чтобы это было (a=1 OR b=2) AND c=3?
Практический пример: фильтрация заказов
Задача: выбрать заказы, которые нужно срочно обработать — статус «pending» или «processing», и сумма заказа больше 10000 рублей.
SELECT order_id, status, total_amount
FROM orders
WHERE (status = 'pending' OR status = 'processing')
AND total_amount > 10000;
Скобки вокруг OR обязательны — без них AND «привяжется» только к status = 'processing', и в результат попадут все pending-заказы независимо от суммы.
Таблица истинности AND и OR
Для понимания логических операторов полезна таблица истинности:
A | B | A AND B | A OR B
------+-------+---------+--------
TRUE | TRUE | TRUE | TRUE
TRUE | FALSE | FALSE | TRUE
FALSE | TRUE | FALSE | TRUE
FALSE | FALSE | FALSE | FALSE
AND возвращает TRUE только когда оба операнда TRUE. OR возвращает TRUE, когда хотя бы один TRUE.
В SQL есть третье состояние — NULL («неизвестно»). Это делает логику немного сложнее:
TRUE AND NULL → NULL
FALSE AND NULL → FALSE (FALSE AND что угодно = FALSE)
TRUE OR NULL → TRUE (TRUE OR что угодно = TRUE)
FALSE OR NULL → NULL
Это поведение важно при работе с колонками, которые могут содержать NULL. Подробнее — в модуле 4.
Типичные ошибки
1. Попытка написать «человеческое» условие:
WHERE department = 'Разработка' OR 'Дизайн' -- ошибка!
WHERE department = 'Разработка' OR 'Дизайн'
-- нужно:
WHERE department = 'Разработка' OR department = 'Дизайн'
SQL требует полного условия с каждой стороны OR. Нельзя «сократить» повторение имени колонки.
2. Смешивание AND и OR без скобок:
WHERE category = 'Электроника' OR category = 'Книги' AND price < 500
-- Это значит: category='Электроника' OR (category='Книги' AND price<500)
-- Возможно, вы хотели: (category='Электроника' OR category='Книги') AND price<500
3. NOT с несколькими условиями:
WHERE NOT department = 'IT' OR department = 'HR'
-- Это: (NOT department='IT') OR department='HR'
-- Скорее всего имелось в виду: NOT (department='IT' OR department='HR')
Читаемость составных условий
Когда условий много, запрос может стать трудным для понимания. Несколько приёмов для улучшения читаемости:
Выравнивание по AND/OR:
SELECT name, department, salary
FROM employees
WHERE department = 'Разработка'
AND salary > 80000
AND salary < 120000;
Группировка с комментариями:
SELECT order_id, status, total_amount
FROM orders
WHERE -- условия по статусу
(status = 'pending' OR status = 'processing')
AND -- условия по сумме
total_amount > 10000;
Такой стиль особенно полезен, когда условий 4–5 и более.
Несколько AND: диапазонные условия
Для проверки диапазона значений используют два AND-условия подряд:
SELECT name, salary
FROM employees
WHERE salary >= 80000
AND salary <= 110000;
Это вернёт сотрудников с зарплатой от 80000 до 110000 включительно. В следующем модуле мы познакомимся с оператором BETWEEN, который делает то же самое более компактно. Но AND всегда остаётся доступной альтернативой.
Реальный запрос: поиск по нескольким критериям
Задача из жизни: найти подходящих кандидатов для продвижения — сотрудники из IT, со стажем более 3 лет и зарплатой ниже рыночной (условно меньше 100000):
SELECT name, department, experience_years, salary
FROM employees
WHERE department = 'IT'
AND experience_years > 3
AND salary < 100000;
Три условия AND — строка попадает только если удовлетворяет всем трём. Логика однозначная, скобки не нужны — здесь только AND, приоритет не имеет значения.
Краткий итог
AND— строка попадает, если оба условия истинныOR— строка попадает, если хотя бы одно условие истинноNOT— инвертирует результат условия- Приоритет:
NOT>AND>OR;AND«привязывается» сильнее, чемOR - При смешивании
ANDиORвсегда используйте скобки - Каждое условие при
ORдолжно быть полным:department = 'A' OR department = 'B' - Хороший стиль: выравнивание AND/OR, комментарии при сложных условиях
Что дальше
Вы умеете строить составные условия фильтрации. Следующая задача — управлять порядком строк в результате. Клауза ORDER BY сортирует результат по любой колонке, в любом направлении. Разберём её в следующем уроке.