ИТ.03 - 05 - Составные условия запросов AND, OR, NOT. Специальные операторы IN и BETWEEN. Модификатор запроса DISTINCT
Введение
В предыдущей теме мы познакомились с базовыми конструкциями SQL — SELECT, FROM и WHERE.
Сегодня разберём специальные и логические операторы, которые позволяют гибко управлять выборкой данных и делать запросы более точными.
Логические операторы
Используются для объединения или отрицания условий фильтрации:
AND— оба условия должны выполняться;OR— достаточно выполнения одного условия;NOT— исключает строки, подходящие под условие;XOR— выполняется только одно из условий, но не оба.
Специальные операторы
Помогают работать со списками и диапазонами:
IN— проверяет, входит ли значение в указанный набор;BETWEEN— проверяет, находится ли значение в пределах заданного диапазона.
Модификатор выборки
DISTINCT— исключает дублирующиеся строки из результата запроса.
Эти инструменты часто комбинируются в одном запросе, делая фильтрацию данных гибкой и читаемой.
Учебная база данных «Retail Orders»
| id | user_id | price | status |
|---|---|---|---|
| 1 | 1 | 1300 | new |
| 2 | 18 | 10000 | cancelled |
| 3 | 45 | 800 | cancelled |
| 4 | 11 | 2140 | in_progress |
| 5 | 145 | 6800 | new |
| 6 | 23 | 999 | new |
| 7 | 1 | 7690 | cancelled |
| 8 | 17 | 1600 | new |
| 9 | 5 | 400 | delivery |
| 10 | 11 | 1450 | new |
| 11 | 18 | 13000 | cancelled |
| 12 | 11 | 1000 | in_progress |
| 13 | 45 | 3000 | returned |
Журнал заказов интернет-магазина комплектующих: фиксируются клиенты, суммы и статусы, что позволяет показывать составные условия и фильтры.
Особенности:
- содержит повторяющихся клиентов и разные статусы;
- удобно демонстрировать
AND/OR/NOT,IN,BETWEEN,DISTINCT; - допускает
NULLв некоторых полях для примеров с отсутствием данных.
Поля
ordersid— целочисленный первичный ключ;user_id— идентификатор покупателя (может отсутствовать);price— сумма заказа в рублях;status— текстовый статус (new,cancelled,delivery,returned,in_progress).
Ограничения
- Единственным строго уникальным столбцом является
id; поля могут быть пустыми, но по умолчанию заполнены значениями.
Скачать в виде файла: retail_orders_sqlite.sql
CREATE TABLE
orders (
id INT PRIMARY KEY,
user_id INT NULL,
price INT NULL,
status VARCHAR(20) NULL
)
;
INSERT INTO
orders (id, user_id, price, status)
VALUES
(1, 1, 1300, 'new'),
(2, 18, 10000, 'cancelled'),
(3, 45, 800, 'cancelled'),
(4, 11, 2140, 'in_progress'),
(5, 145, 6800, 'new'),
(6, 23, 999, 'new'),
(7, 1, 7690, 'cancelled'),
(8, 17, 1600, 'new'),
(9, 5, 400, 'delivery'),
(10, 11, 1450, 'new'),
(11, 18, 13000, 'cancelled'),
(12, 11, 1000, 'in_progress'),
(13, 45, 3000, 'returned')
;
Оператор AND
Оператор AND используется, когда нужно выбрать строки, удовлетворяющие всем условиям одновременно.
SELECT id, user_id, price, status
FROM orders
WHERE status = 'new' AND price > 1000;
Результат:
Отбираются только заказы со статусом new, сумма которых превышает 1000.
Оператор OR
Оператор OR возвращает строки, где выполняется хотя бы одно из указанных условий.
SELECT id, user_id, price, status
FROM orders
WHERE status = 'cancelled' OR status = 'returned';
Результат:
Отбираются все отменённые (cancelled) и возвращённые (returned) заказы.
Оператор NOT
Оператор NOT исключает строки, удовлетворяющие условию.
SELECT id, user_id, price, status
FROM orders
WHERE NOT status = 'cancelled';
Результат:
Выводятся все заказы, кроме отменённых.
Приоритет операторов
Порядок выполнения в SQL следующий:
NOTANDOR
Чтобы задать свой порядок, используйте скобки ().
SELECT id, user_id, price, status
FROM orders
WHERE (status = 'new' OR status = 'in_progress') AND price < 2000;
Результат:
Отбираются заказы в статусах new или in_progress, при этом сумма меньше 2000.
Оператор XOR
Оператор XOR (исключающее ИЛИ) используется редко,
но бывает полезен, когда нужно выбрать строки, где только одно из двух условий истинно, а если оба выполняются — строка не попадёт в результат.
SELECT id, user_id, price, status
FROM orders
WHERE (price > 5000) XOR (status = 'new');
Результат:
Будут показаны заказы, где либо сумма больше 5000,
либо статус "new", но не оба одновременно.
Примечание
Поддержка XOR зависит от диалекта SQL.
В MySQL он есть, а в SQLite можно заменить выражением:
SELECT id, user_id, price, status
FROM orders
WHERE
(price > 5000 AND status != 'new')
OR
(price <= 5000 AND status = 'new')
;
Оператор IN
Оператор IN используется для проверки, входит ли значение в указанный список.
Он делает запросы короче и нагляднее, чем несколько OR.
SELECT id, user_id, price, status
FROM orders
WHERE status IN ('cancelled', 'returned', 'delivery');
Результат:
Отбираются все заказы, у которых статус — cancelled, returned или delivery.
Аналогичный запрос через OR:
SELECT id, user_id, price, status
FROM orders
WHERE
status = 'cancelled'
OR
status = 'returned'
OR
status = 'delivery'
;
Оператор BETWEEN
Оператор BETWEEN используется для проверки, входит ли значение в заданный диапазон включительно.
Он делает запросы короче и нагляднее, чем два условия с AND.
SELECT id, user_id, price, status
FROM orders
WHERE price BETWEEN 1000 AND 5000;
Результат:
Выводятся заказы, сумма которых от 1000 до 5000 включительно.
Аналогичный запрос через AND:
SELECT id, user_id, price, status
FROM orders
WHERE
price >= 1000
AND
price <= 5000
;
Совет
Диапазон можно использовать и с датами — SQL корректно сравнивает даты по порядку.
DISTINCT — уникальные значения
DISTINCT используется, чтобы убрать дубли в результатах запроса.
SELECT DISTINCT status
FROM orders;
Результат:
Показывает список уникальных статусов заказов без повторений.
Комбинация DISTINCT и WHERE
Можно объединять DISTINCT с условиями фильтрации:
SELECT DISTINCT user_id
FROM orders
WHERE status = 'cancelled';
Результат:
Выводятся уникальные пользователи, у которых есть хотя бы один отменённый заказ.
Практические задания
Задание 1. AND + числовое сравнение по нескольким условиям
Выведите все новые заказы (new), сумма которых больше 1500.
-- Ваш код можете писать тут
SELECT *
FROM orders
WHERE
status = "new"
AND
price >= 1500
Задание 2. OR — фильтр по нескольким статусам
Выведите заказы, которые либо отменены (cancelled), либо возвращены (returned).
В решении не используйте оператор IN.
-- Ваш код можете писать тут
SELECT *
FROM orders
WHERE
status = "cancelled"
OR
status = "returned"
Задание 3. NOT IN — исключение ненужных статусов
Выведите все заказы, кроме тех, что находятся в доставке (delivery) или в обработке (in_progress).
В решении не используйте символ != и оператор OR.
-- Ваш код можете писать тут
SELECT *
FROM orders
WHERE
status NOT IN("delivery", "in_progress")
Задание 4. BETWEEN — выборка по интервалу сумм
Выведите все заказы, сумма которых находится в диапазоне от 2000 до 7000 включительно.
В решении не используйте символы >= или <=.
-- Ваш код можете писать тут
SELECT *
FROM orders
WHERE
price BETWEEN 2000 AND 7000
Задание 5. DISTINCT — уникальные значения столбца
Выведите все уникальные значения статусов заказов.
-- Ваш код можете писать тут
SELECT DISTINCT
status
FROM orders
Задание 6. IN + DISTINCT — пользователи с выбранными статусами
Найдите всех уникальных пользователей, у которых есть новые (new), отмененные (cancelled) или возвращенные (returned) заказы.
В решении не используйте символ = и оператор OR.
-- Ваш код можете писать тут
SELECT DISTINCT
user_id
FROM orders
WHERE
status IN('new', 'cancelled', 'returned')