IN и BETWEEN
Проверка по списку значений и по диапазону
Теория
Из предыдущих тем становится понятно, что условий в предложении WHERE может быть много, и они могут быть одинаковыми по своему типу.
Например, нужно:
• выбрать пользователей из нескольких конкретных городов;
• показать товары в определённом диапазоне цен;
• найти заказы за нужный промежуток дат.
В таких случаях фильтрацию в SQL-запросе можно записать короче и понятнее, избежав синтаксического дублирования.
Для этого есть два удобных оператора:
• IN — когда нужно проверить, входит ли значение в список;
• BETWEEN — когда нужно проверить, попадает ли значение в диапазон.
IN по сути является короткой заменой нескольких однотипных условий через OR. Вместо длинной записи вида city = 'Москва' OR city = 'Алматы' OR city = 'Казань' можно написать компактнее: city IN ('Москва', 'Алматы', 'Казань').
BETWEEN помогает выразить диапазон без пары сравнений. Например, вместо price >= 50000 AND price <= 100000 можно написать price BETWEEN 50000 AND 100000.
Важно: BETWEEN включает обе границы. То есть если значение равно нижней или верхней границе, оно тоже попадёт в результат.
Например, нужно:
• выбрать пользователей из нескольких конкретных городов;
• показать товары в определённом диапазоне цен;
• найти заказы за нужный промежуток дат.
В таких случаях фильтрацию в SQL-запросе можно записать короче и понятнее, избежав синтаксического дублирования.
Для этого есть два удобных оператора:
• IN — когда нужно проверить, входит ли значение в список;
• BETWEEN — когда нужно проверить, попадает ли значение в диапазон.
IN по сути является короткой заменой нескольких однотипных условий через OR. Вместо длинной записи вида city = 'Москва' OR city = 'Алматы' OR city = 'Казань' можно написать компактнее: city IN ('Москва', 'Алматы', 'Казань').
BETWEEN помогает выразить диапазон без пары сравнений. Например, вместо price >= 50000 AND price <= 100000 можно написать price BETWEEN 50000 AND 100000.
Важно: BETWEEN включает обе границы. То есть если значение равно нижней или верхней границе, оно тоже попадёт в результат.
Синтаксис
SELECT column1, -- указываем столбцы, которые хотим получить
column2,
column3
FROM table_name -- указываем таблицу, из которой берём данные
WHERE column_name IN (value1, value2, value3); -- оставляем строки, где column_name совпадает с одним из значений списка
SELECT column1,
column2,
column3
FROM table_name
WHERE column_name BETWEEN start_value AND end_value; -- оставляем строки, где column_name находится в указанном диапазоне между start_value включительно и end_value включительно
SQL
IN работает со списком значений. Это могут быть числа, строки или даты.
Примеры:
• department_id IN (1, 3, 5)
• city IN ('Москва', 'Алматы')
BETWEEN работает с диапазоном. Чаще всего его используют для чисел и дат.
Примеры:
• price BETWEEN 50000 AND 100000
• order_date BETWEEN '2024-01-01' AND '2024-03-31'
Если требуется строгий диапазон без включения границ, то лучше использовать стандартные сравнения с помощью операторов >, < и AND.
Примеры:
• department_id IN (1, 3, 5)
• city IN ('Москва', 'Алматы')
BETWEEN работает с диапазоном. Чаще всего его используют для чисел и дат.
Примеры:
• price BETWEEN 50000 AND 100000
• order_date BETWEEN '2024-01-01' AND '2024-03-31'
Если требуется строгий диапазон без включения границ, то лучше использовать стандартные сравнения с помощью операторов >, < и AND.
Примеры
1. Выбираем работников из нескольких отделов
Здесь оператор IN заменяет несколько однотипных условий для разных отделов. Это делает запрос короче и более удобным для восприятия, чем длинная цепочка условий через OR.
🔄 Попробуйте изменить запрос:
- • Замените список на (2, 3, 5) и сравните выборку
- • Попробуйте получить такой же результат, только не через IN, а через OR
2. Ищем пользователей из конкретных городов
Этот подход аналогичен, но применяется к текстовым значениям. Когда существует несколько вариантов, использование IN упрощает и делает условие более коротким.
🔄 Попробуйте изменить запрос:
- • Поменяйте один из городов в списке
- • Добавьте условие AND registration_date >= '2023-07-01'
3. Показываем товары в нужном диапазоне цен
Оператор BETWEEN используется для проверки диапазона цен. В выборку войдут товары, стоимость которых находится в пределах от 30 000 до 90 000 включительно.
🔄 Попробуйте изменить запрос:
- • Поменяйте границы диапазона на 50000 и 120000
- • Перепишите это условие без BETWEEN через два сравнения с операторами < , > и AND
4. Находим заказы за определённый период и с нужными статусами
Данный пример иллюстрирует сочетание диапазона дат и списка допустимых статусов. Это позволяет одновременно использовать операторы BETWEEN и IN в одном запросе.
🔄 Попробуйте изменить запрос:
- • Замените список статусов на ('доставлен', 'отменён')
- • Перед оператором IN добавьте NOT, проанализируйте результат и объясните логику фильтрации в этом случае
Типичные ошибки
Думают, что BETWEEN не включает границы
На самом деле включает. Условие price BETWEEN 30000 AND 90000 захватит и 30000, и 90000.
Забывают кавычки для текста и дат внутри IN
Числа пишутся без кавычек, а строки и даты — с кавычками. Например: city IN ('Москва', 'Казань').
Путают IN с несколькими значениями в одном сравнении
Запись вида city = ('Москва', 'Казань') не подходит. Если значений несколько, нужен именно IN. Оператор = работает только тогда, когда сравнивается с одним значением, а не списком.
Неправильно задают диапазон через BETWEEN
Нижняя граница должна идти первой, верхняя — второй. Если перепутать их местами, результат будет не таким, как ожидалось, а точнее его просто не будет.
Неосторожно используют NOT IN рядом с NULL
Если в списке для NOT IN появляется NULL, логика становится неочевидной и результат может удивить. В таких местах лучше быть особенно внимательным.
Практика
Проверь себя
Ответьте на вопросы, чтобы закрепить материал:
1
Какую запись удобнее всего использовать, если нужно оставить только отделы 2, 4 и 5?
2
Что важно помнить про условие salary BETWEEN 60000 AND 90000?
3
Как короче всего переписать условие city = 'Москва' OR city = 'Минск'?
4
Что вернёт выражение SELECT 75000 BETWEEN 60000 AND 90000;? Введите только результат: TRUE или FALSE.
5
Напишите запрос к таблице workers, который выведет worker_id, first_name, department_id и salary только для работников из отделов 2, 4 и 5, у которых зарплата находится в диапазоне от 60000 до 95000 включительно. Сначала должны идти большие зарплаты, а при равной зарплате — меньший worker_id.
6
Какое условие точнее всего соответствует диапазону без включения границ от 50000 до 90000?
7
Напишите запрос к таблице order_items, который выведет order_item_id, order_id, product_id и quantity только для строк, где product_id входит в список (2, 5, 8, 11), а quantity находится в диапазоне от 2 до 6 включительно. Сначала должны идти строки с большим количеством товаров, а при равном количестве — меньший order_item_id.