Приоритет операторов и скобки

Приоритет операторов и скобки

В уроке про AND, OR и NOT мы кратко затронули тему приоритета операторов. Это достаточно важная тема, чтобы посвятить ей отдельный урок. Ошибки с приоритетом операторов особенно коварны: запрос выполняется без ошибок, возвращает данные, но не те, которые вы ожидали. Такие баги сложно заметить и легко пропустить.

Что такое приоритет операторов

Приоритет — это порядок, в котором операторы вычисляются, когда в одном выражении их несколько. Вы знаете это из математики: 2 + 3 * 4 равно 14, а не 20, потому что умножение имеет более высокий приоритет, чем сложение.

В SQL та же идея применяется к логическим операторам в WHERE. Когда вы пишете составное условие без скобок, SQL вычисляет его по правилам приоритета, а не слева направо.

Иерархия приоритетов в SQL

От высшего к низшему:

ПриоритетОператоры
ВысшийАрифметика: *, /, %
Сложение/вычитание: +, -
Операторы сравнения: =, <>, <, >, <=, >=
IS [NOT] NULL, LIKE, BETWEEN, IN
NOT
AND
НизшийOR

Ключевое правило: AND выполняется до OR. NOT выполняется до AND.

Пример: AND перехватывает OR

Рассмотрим знакомый пример:

SELECT * FROM employees
WHERE department = 'Разработка'
   OR department = 'Дизайн'
  AND salary > 80000;

Из-за приоритета (AND раньше OR) это читается как:

WHERE department = 'Разработка'
   OR (department = 'Дизайн' AND salary > 80000)

Результат: все разработчики (без ограничений по зарплате) ПЛЮС дизайнеры с зарплатой выше 80000.

Если вы хотели «разработчики или дизайнеры, но только с зарплатой выше 80000», нужны скобки:

WHERE (department = 'Разработка' OR department = 'Дизайн')
  AND salary > 80000

Два внешне похожих запроса дают принципиально разные результаты. Именно поэтому скобки — не опциональный стиль, а защита от ошибок.

Пример: NOT инвертирует больше, чем кажется

Ещё одна ловушка — с NOT:

WHERE NOT department = 'IT' OR salary > 100000

Из-за приоритета это читается как:

WHERE (NOT department = 'IT') OR salary > 100000

То есть: «не-IT-шники» ПЛЮС все с зарплатой выше 100000 (в том числе из IT). Скорее всего имелось в виду:

WHERE NOT (department = 'IT' OR salary > 100000)

Что означает: «не-IT-шники с зарплатой не выше 100000». Полностью разная семантика.

Проверь себя: что вернёт WHERE a = 1 OR b = 2 AND c = 3? Как расставить скобки для (a=1 OR b=2) AND c=3?

Арифметика и сравнения

Арифметика вычисляется до логических операторов, поэтому такие выражения работают ожидаемо:

WHERE price * quantity > 10000 AND discount < 0.2

Сначала price * quantity (арифметика), затем > 10000 (сравнение), затем AND.

Но скобки всё равно полезны для наглядности:

WHERE (price * quantity > 10000) AND (discount < 0.2)

Явный смысл: «суммарная стоимость больше 10000 И скидка меньше 20%».

Скобки как документация

Скобки выполняют двойную роль: они управляют вычислением И служат документацией намерений. Читатель запроса не обязан держать в голове таблицу приоритетов. Скобки говорят явно: «эти условия — одна группа».

Сравните два записи одного и того же логического условия:

-- Без скобок (требует знания приоритетов)
WHERE status = 'active' AND age >= 18 OR status = 'pending' AND age >= 16

-- Со скобками (намерение очевидно)
WHERE (status = 'active' AND age >= 18)
   OR (status = 'pending' AND age >= 16)

Второй вариант однозначно читается как: «либо активные совершеннолетние, либо ожидающие одобрения с 16 лет». Первый требует применения правила приоритета в голове.

Когда скобки не нужны

Если условие содержит только AND или только OR (без смешивания), скобки добавляют визуальный шум без пользы:

-- Только AND — скобки не нужны
WHERE department = 'IT' AND salary > 50000 AND hire_year > 2020

-- Только OR — скобки тоже лишние
WHERE status = 'active' OR status = 'pending' OR status = 'trial'

Здесь нет неоднозначности — приоритет одинаков для всех операторов, порядок вычисления очевиден.

Скобки становятся необходимыми при смешивании AND и OR в одном условии.

Вложенные скобки

Скобки можно вкладывать на любую глубину:

WHERE (department = 'IT' AND (salary > 80000 OR experience > 5))
   OR (department = 'HR' AND salary > 60000)

Вычисление: сначала самые внутренние скобки (salary > 80000 OR experience > 5), затем AND department = 'IT', затем OR (department = 'HR' AND salary > 60000).

Это сложное условие, но со скобками его можно прочитать последовательно. Без скобок такое условие было бы почти нечитаемым.

Практика: найдите ошибку

Задача: найти активных клиентов из Москвы или Санкт-Петербурга. Разработчик написал:

SELECT name, city, status
FROM   customers
WHERE  city = 'Москва' OR city = 'Санкт-Петербург' AND status = 'active';

Что здесь не так? Из-за приоритета AND это читается как:

WHERE city = 'Москва' OR (city = 'Санкт-Петербург' AND status = 'active')

Результат: все клиенты из Москвы (независимо от статуса!) плюс активные из Санкт-Петербурга. Москвичи без статуса 'active' тоже попадут в результат — что является ошибкой.

Правильный запрос:

SELECT name, city, status
FROM   customers
WHERE  (city = 'Москва' OR city = 'Санкт-Петербург')
  AND  status = 'active';

Это вернёт только активных клиентов из обоих городов.

Трассировка: пошаговое вычисление сложного условия

Разберём сложное условие пошагово, как это делает СУБД:

Условие: a = 1 OR b = 2 AND c = 3 AND d = 4

Шаг 1 — находим все AND (высший приоритет):

  • b = 2 AND c = 3 → группа B
  • группа B AND d = 4 → группа C

Шаг 2 — применяем OR:

  • a = 1 OR группа C

Итоговая логика: a = 1 OR ((b = 2 AND c = 3) AND d = 4)

Если вы хотели (a=1 OR b=2) AND c=3 AND d=4 — без скобок это невозможно, нужно написать явно:

WHERE (a = 1 OR b = 2) AND c = 3 AND d = 4

Практические правила для команды

Если вы работаете в команде над одной кодовой базой, стоит выработать соглашение о скобках. Два разумных подхода:

Консервативный: всегда ставить скобки при смешивании AND и OR, даже если они технически не нужны по приоритету.

Минималистичный: скобки только там, где они меняют порядок вычисления (не где он совпадает с приоритетом).

Оба подхода рабочие. Важно — последовательность. «Иногда скобки, иногда нет» — хуже обоих вариантов, потому что читатель не знает, намеренно ли они отсутствуют.

Проверка через упрощённые подстановки

Хороший способ убедиться, что логика правильная — подставить конкретные значения и проверить, совпадает ли результат с ожидаемым.

Условие: WHERE status = 'active' OR role = 'admin' AND verified = true

Тест 1: status='inactive', role='admin', verified=true

  • status='active' → FALSE
  • role='admin' AND verified=true → TRUE AND TRUE → TRUE
  • FALSE OR TRUE → TRUE ← попадает в результат

Вопрос: хотели ли мы, чтобы неактивные администраторы попадали в результат? Если нет — нужны скобки: (status='active' OR role='admin') AND verified=true.

Такая проверка с «граничными» тестовыми данными помогает поймать логические ошибки до того, как они попадут в продакшн.

Краткий итог

  • Приоритет логических операторов: NOT > AND > OR
  • AND вычисляется до OR — это главное правило для условий WHERE
  • При смешивании AND и OR всегда используйте скобки
  • Скобки не только управляют вычислением, но и документируют намерение
  • Проверяйте сложные условия подстановкой граничных значений
  • При только AND или только OR скобки добавляют шум — их можно не ставить

Что дальше

Финальный урок этого модуля — практика с типичными ошибками в условиях WHERE. Вы увидите реальные примеры запросов с ошибками и научитесь их находить и исправлять. Это закрепит всё, что мы изучили в модуле 3.

Попробуйте интерактивную версию

Практические задачи, квизы и AI-наставник — бесплатный старт без карты

Перейти к практике