BETWEEN: диапазоны

BETWEEN: диапазоны

В предыдущем уроке вы освоили IN для проверки вхождения в список конкретных значений. Теперь рассмотрим смежную задачу: фильтрацию по диапазону. «Товары ценой от 1000 до 5000», «заказы за последние три месяца», «сотрудники с зарплатой от 80000 до 120000». Конечно, это можно записать через два условия с AND:

WHERE price >= 1000 AND price <= 5000

Работает корректно. Но SQL предоставляет более читабельную альтернативу — оператор BETWEEN.

Синтаксис BETWEEN

SELECT колонки
FROM   таблица
WHERE  колонка BETWEEN нижняя_граница AND верхняя_граница;

Эквивалент через AND:

WHERE price BETWEEN 1000 AND 5000
-- то же самое, что:
WHERE price >= 1000 AND price <= 5000

Обе границы в BETWEEN включены в диапазон. Это важная деталь — BETWEEN 1000 AND 5000 включает и 1000, и 5000.

Пример: товары в ценовом диапазоне 2000–10000 рублей:

SELECT name, price, category
FROM   products
WHERE  price BETWEEN 2000 AND 10000
ORDER BY price ASC;

Результат включит товары с ценой ровно 2000 и ровно 10000.

Проверь себя: что вернёт WHERE score BETWEEN 90 AND 100 для строки со score = 90?

BETWEEN с датами

BETWEEN особенно удобен для фильтрации по датам. Запрос заказов за конкретный месяц:

SELECT order_id, created_at, total_amount
FROM   orders
WHERE  created_at BETWEEN '2024-01-01' AND '2024-01-31'
ORDER BY created_at;

Это вернёт все заказы с 1 по 31 января 2024 года включительно.

Важный нюанс с TIMESTAMP: если колонка хранит дату и время (TIMESTAMP), то '2024-01-31' интерпретируется как '2024-01-31 00:00:00'. Заказы в 23:59 31 января не войдут в результат! Правильный способ:

WHERE created_at >= '2024-01-01'
  AND created_at  < '2024-02-01'   -- строго меньше начала следующего месяца

Или явно с временем:

WHERE created_at BETWEEN '2024-01-01 00:00:00' AND '2024-01-31 23:59:59'

Это типичная ловушка при работе с датами и BETWEEN. При числах и датах без времени BETWEEN работает интуитивно, но с TIMESTAMP — будьте внимательны.

NOT BETWEEN: за пределами диапазона

NOT BETWEEN возвращает строки, где значение выходит за пределы диапазона:

SELECT name, price
FROM   products
WHERE  price NOT BETWEEN 1000 AND 5000;

Это вернёт товары дешевле 1000 рублей или дороже 5000. Эквивалент:

WHERE price < 1000 OR price > 5000

Обе границы при NOT BETWEEN тоже исключены. То есть товар с price = 1000 попадёт под price NOT BETWEEN 1000 AND 5000? Нет — он точно на границе BETWEEN, поэтому NOT BETWEEN его исключает.

Порядок границ важен

В BETWEEN нижняя граница должна быть меньше верхней. Если перепутать:

WHERE price BETWEEN 5000 AND 1000   -- вернёт 0 строк!

PostgreSQL не выдаст ошибку, но вернёт пустой результат: нет числа, которое одновременно >= 5000 и <= 1000.

Всегда пишите: BETWEEN минимум AND максимум.

BETWEEN со строками

BETWEEN работает и со строками, применяя лексикографическое сравнение:

SELECT name FROM employees WHERE name BETWEEN 'А' AND 'Д';

Это вернёт имена, лексикографически находящиеся между «А» и «Д»: Анна, Борис, Вера, Гриша, Дина, Дмитрий.

На практике строковый BETWEEN используют редко — поведение зависит от локали базы и может быть неочевидным. Лучше использовать явные условия >= 'А' AND < 'Е' или LIKE-шаблоны.

BETWEEN vs два условия AND: когда что выбрать

BETWEEN лучше, когда:

  • Обе границы включены (что соответствует семантике BETWEEN)
  • Диапазон числовой или датовый (без времени)
  • Важна читабельность запроса

Два условия с >= и < лучше, когда:

  • Нужна «полуоткрытая» граница: >= '2024-01-01' AND < '2024-02-01'
  • Одна из границ динамически вычисляется
  • Нужна разная логика для верхней и нижней границы

На практике оба подхода встречаются в боевом коде. Выбирайте тот, что лучше отражает смысл условия.

Практический пример: аналитика продаж

Задача: отчёт по продажам за квартал — все заказы Q1 2024 с суммой от 5000 до 100000 рублей:

SELECT order_id,
       customer_id,
       created_at,
       total_amount
FROM   orders
WHERE  created_at  BETWEEN '2024-01-01' AND '2024-03-31'
  AND  total_amount BETWEEN 5000 AND 100000
ORDER BY total_amount DESC;

Два BETWEEN условия объединены через AND. Строки попадают в результат только если удовлетворяют обоим диапазонам.

Другой пример — найти сотрудников среднего уровня зарплаты:

SELECT name, department, salary
FROM   employees
WHERE  salary BETWEEN 60000 AND 120000
  AND  department IN ('Разработка', 'QA', 'DevOps')
ORDER BY department, salary DESC;

Комбинирование BETWEEN и IN — типичный паттерн в аналитических запросах.

Типичные ошибки

1. Перепутаны границы:

WHERE age BETWEEN 30 AND 18  -- 0 строк, нужно BETWEEN 18 AND 30

2. BETWEEN с TIMESTAMP — потеря строк:

WHERE created_at BETWEEN '2024-01-01' AND '2024-01-31'
-- Не включит заказы 31 января после 00:00:00
-- Используйте: >= '2024-01-01' AND < '2024-02-01'

3. Путаница: BETWEEN включает обе границы:

-- Хотели ИСКЛЮЧИТЬ границы (открытый интервал)
WHERE price BETWEEN 100 AND 500  -- включает 100 и 500
-- Для открытого интервала: WHERE price > 100 AND price < 500

Диапазоны в разных СУБД

BETWEEN ... AND ... — стандартный SQL, работает одинаково во всех СУБД: PostgreSQL, SQLite, MySQL, SQL Server. Единственное отличие может быть в обработке граничных значений для специфических типов данных, но для чисел и стандартных дат поведение идентично.

В SQL Server есть дополнительный синтаксис для работы с датами (DATEADD, DATEDIFF), но BETWEEN работает там так же, как в PostgreSQL.

Как BETWEEN работает под капотом

Когда СУБД видит WHERE price BETWEEN 1000 AND 5000, она внутренне преобразует это в WHERE price >= 1000 AND price <= 5000. Это не упрощение — это буквальная трансформация, которую выполняет планировщик запросов перед оптимизацией.

Именно поэтому:

  • BETWEEN поддерживает использование индексов так же, как два >=/<= условия
  • NOT BETWEEN a AND b эквивалентно NOT (col >= a AND col <= b), что по законам де Моргана равно col < a OR col > b
  • СУБД не делает разницы между этими формами при оптимизации

Знание этого эквивалента помогает понять, что BETWEEN — синтаксический сахар, а не магия.

Диапазон с одинаковыми границами

Что если BETWEEN a AND a — обе границы одинаковые?

WHERE score BETWEEN 100 AND 100
-- эквивалентно: WHERE score >= 100 AND score <= 100
-- то же самое что: WHERE score = 100

Это работает, но написать = 100 проще и понятнее. BETWEEN a AND a — формально корректно, но на практике так не пишут.

Комбинирование нескольких BETWEEN

Можно фильтровать по нескольким диапазонам одновременно:

SELECT product_id, name, price, rating
FROM   products
WHERE  price  BETWEEN 1000 AND 15000
  AND  rating BETWEEN 4.0 AND 5.0;

Это вернёт товары в ценовом диапазоне 1000–15000 рублей и с рейтингом от 4.0 до 5.0. Оба условия BETWEEN объединяются через AND.

Ещё пример — отчёт о пользователях среднего возраста с определённым числом заказов:

SELECT user_id, name, age, order_count
FROM   user_stats
WHERE  age         BETWEEN 25 AND 45
  AND  order_count BETWEEN 3 AND 20
ORDER BY order_count DESC;

Такие запросы типичны в аналитике: «пользователи в нужном сегменте по нескольким критериям».

BETWEEN в ON-клаузе JOIN

BETWEEN можно использовать не только в WHERE, но и в условиях соединения таблиц (ON). Это более продвинутая тема — JOIN мы подробно разберём в модуле 6. Но стоит знать, что BETWEEN не ограничен только WHERE.

Краткий итог

  • BETWEEN a AND b — значение в диапазоне [a, b] включительно (обе границы входят)
  • NOT BETWEEN a AND b — значение вне диапазона (строго меньше a или строго больше b)
  • Нижняя граница должна быть ≤ верхней; перепутаные границы дадут 0 строк
  • BETWEEN эквивалентен >= a AND <= b — СУБД использует их одинаково
  • С TIMESTAMP-колонками осторожно: BETWEEN '2024-01-31' не включает конец дня
  • Для полуоткрытых интервалов (>= a AND < b) BETWEEN не подходит
  • BETWEEN работает одинаково во всех основных СУБД

Что дальше

Вы освоили диапазоны с BETWEEN. Следующая тема — одна из самых важных в SQL: специальное значение NULL и операторы IS NULL / IS NOT NULL. Понимание NULL критично для правильного написания запросов, потому что его поведение часто удивляет разработчиков из других языков программирования.

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

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

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