← Назад к вопросам

Какой оператор имеет более высокий приоритет: AND или OR?

1.3 Junior🔥 71 комментариев
#SQL и базы данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Приоритет операторов AND и OR в SQL

Прямой ответ: AND имеет более высокий приоритет, чем OR.

Это означает, что AND выполняется раньше, чем OR при вычислении условий WHERE. Это фундаментальное правило в логике и SQL, которое критично понимать для написания корректных запросов.

Объяснение приоритета

При наличии нескольких логических операторов SQL выполняет их в следующем порядке:

1. AND (высший приоритет)
2. OR (низший приоритет)

Пример с приоритетом AND

-- Запрос:
SELECT * FROM users
WHERE age > 18 AND city = 'Moscow' OR city = 'SPB';

-- Интерпретируется как:
WHERE (age > 18 AND city = 'Moscow') OR (city = 'SPB');

-- НЕ как:
WHERE age > 18 AND (city = 'Moscow' OR city = 'SPB');

Это означает:

  • Группа 1: возраст > 18 И город Moscow (выполняется вместе)
  • ИЛИ
  • Группа 2: город SPB (отдельное условие)

Результат включает:

  1. Пользователей из Moscow старше 18 лет
  2. ВСЕ пользователей из SPB (независимо от возраста!)

Пример с данными

Таблица users:
id | name    | age | city
1  | Alice   | 25  | Moscow
2  | Bob     | 16  | Moscow
3  | Charlie | 30  | SPB
4  | Diana   | 15  | SPB
5  | Eve     | 22  | Kazan

Запрос: WHERE age > 18 AND city = 'Moscow' OR city = 'SPB';

Этапы вычисления:
id | age > 18 | city = 'Moscow' | AND | city = 'SPB' | OR result
1  | true     | true            | T   | false        | T ✓ (выбран)
2  | false    | true            | F   | false        | F
3  | true     | false           | F   | true         | T ✓ (выбран)
4  | false    | false           | F   | true         | T ✓ (выбран)
5  | true     | false           | F   | false        | F

Результат: Alice (1), Charlie (3), Diana (4)

Правильный способ: используйте скобки

Чтобы избежать ошибок, ВСЕГДА используйте скобки для явного указания приоритета:

-- Вариант 1: пользователи > 18 лет из Moscow ИЛИ ЛЮБЫЕ из SPB
SELECT * FROM users
WHERE (age > 18 AND city = 'Moscow') OR city = 'SPB';

-- Вариант 2: пользователи > 18 лет из Moscow ИЛИ SPB
SELECT * FROM users
WHERE age > 18 AND (city = 'Moscow' OR city = 'SPB');

-- Вариант 3: пользователи из определённых городов И старше 18
SELECT * FROM users
WHERE age > 18 AND city IN ('Moscow', 'SPB');

Бизнес-примеры

Пример 1: Фильтрация заказов

-- Без скобок (опасно!):
SELECT * FROM orders
WHERE status = 'completed' AND amount > 1000 OR payment_method = 'credit_card';

-- Интерпретируется как:
WHERE (status = 'completed' AND amount > 1000) OR payment_method = 'credit_card';

-- Результат: завершённые заказы > 1000 ИЛИ ЛЮБЫЕ заказы по кредитке
-- Может включить незавершённый заказ по кредитке!

-- Правильно:
SELECT * FROM orders
WHERE status = 'completed' AND (amount > 1000 OR payment_method = 'credit_card');

Пример 2: Сегментация пользователей

-- Неправильно (без скобок):
SELECT * FROM users
WHERE account_type = 'premium' AND signup_date > '2024-01-01' 
   OR account_type = 'trial';

-- Это вернёт:
-- 1. Premium пользователей, зарегистрировавшихся после 1 января
-- 2. ВСЕ trial пользователей (включая старых!)

-- Правильно (скобки явно указывают намерение):
SELECT * FROM users
WHERE (account_type = 'premium' AND signup_date > '2024-01-01') 
   OR account_type = 'trial';

-- ИЛИ если нужны недавние trial:
SELECT * FROM users
WHERE signup_date > '2024-01-01' AND (account_type = 'premium' OR account_type = 'trial');

Примеры приоритета в разных СУБД

Приоритет AND > OR одинаков во всех основных СУБД:

  • PostgreSQL
  • MySQL
  • SQL Server
  • Oracle
  • SQLite

NOT оператор

NOT имеет САМЫЙ ВЫСОКИЙ приоритет (выше AND):

-- Приоритет: NOT > AND > OR

SELECT * FROM users
WHERE NOT age > 18 AND city = 'Moscow';

-- Интерпретируется как:
WHERE (NOT age > 18) AND city = 'Moscow';

-- Эквивалентно:
WHERE age <= 18 AND city = 'Moscow';

Таблица приоритета операторов SQL

Приоритет (от высшего к низшему)
1. Скобки ()
2. NOT
3. AND
4. OR

Проверка: SQL запросы с разными приоритетами

-- Данные:
-- id | age | status
-- 1  | 25  | active
-- 2  | 20  | inactive
-- 3  | 30  | inactive
-- 4  | 15  | active

-- Запрос A: AND > OR (приоритет AND выше)
SELECT * FROM users
WHERE age > 18 AND status = 'active' OR status = 'inactive';

-- Выбирает: 1 (25, active), 2 (20, inactive), 3 (30, inactive)
-- Потому что: (age > 18 AND status = 'active') OR status = 'inactive'

-- Запрос B: со скобками (явно)
SELECT * FROM users
WHERE age > 18 AND (status = 'active' OR status = 'inactive');

-- Выбирает: 1 (25, active), 3 (30, inactive)
-- Потому что: age > 18 AND (status = любой)

Практический чеклист

Перед каждым WHERE с AND/OR:

  • Добавлены ли скобки для явной группировки?
  • Правильно ли интерпретируется с приоритетом AND > OR?
  • Протестирован ли результат на известных данных?
  • Нет ли неожиданно большого набора результатов?

Распространённые ошибки

Ошибка 1: Забыли скобки

-- Неправильно:
WHERE status = 'active' AND (region = 'US' OR region = 'EU') AND amount > 100;
-- Правильная интерпретация на самом деле здесь так как AND связывает слева-направо:
WHERE ((status = 'active' AND (region = 'US' OR region = 'EU')) AND amount > 100);

-- Лучше быть явным:
WHERE status = 'active' AND (region = 'US' OR region = 'EU') AND amount > 100;

Ошибка 2: Приоритет запутал результаты

-- Хотел: пользователи, которые (young И active) ИЛИ (premium)
SELECT * FROM users
WHERE age < 25 AND status = 'active' OR type = 'premium';

-- Получил: (young AND active) OR premium
-- Включает ВСЕ premium пользователей!

-- Правильно:
SELECT * FROM users
WHERE (age < 25 AND status = 'active') OR type = 'premium';

Как запомнить

Аналогия из математики:

  • Умножение (×) имеет приоритет над сложением (+)
  • AND ≈ умножение (логическое ×)
  • OR ≈ сложение (логическое +)
  • Поэтому AND выполняется первым
2 + 3 × 4 = 2 + (3 × 4) = 14  (не (2 + 3) × 4 = 20)
A OR B AND C = A OR (B AND C)   (не (A OR B) AND C)

Python аналогия

# Python следует тому же приоритету
age = 25
status = 'active'
city = 'Moscow'

# Эта строка:
if age > 18 and status == 'active' or city == 'Moscow':
    # Интерпретируется как:
    if (age > 18 and status == 'active') or (city == 'Moscow'):
        pass

# Скобки для явности:
if age > 18 and (status == 'active' or city == 'Moscow'):
    pass

Вывод

AND имеет БОЛЕЕ ВЫСОКИЙ приоритет, чем OR.

Это правило:

  • Одинаково во всех СУБД
  • Может привести к ошибкам, если не помнить
  • Легко исправляется скобками

Золотое правило: ВСЕГДА используйте скобки для явного указания приоритета в сложных WHERE условиях. Это делает код понятнее и предотвращает ошибки.