🔍 Урок 2.2 — WHERE: фильтруем строки
Модуль 2: Первые запросы
🎯 Что мы будем делать
В прошлом уроке мы научились читать данные из таблицы с помощью SELECT. Но мы всегда получали ВСЕ строки. А что, если нам нужны не все сотрудники, а только те, кто зарабатывает больше 80000? Или только товары дешевле 5000 рублей? Или только клиенты из Москвы?
Для этого в SQL есть команда WHERE. WHERE — это фильтр. Он отсеивает строки, которые не подходят под условие.
Аналогия: представь, что у тебя корзина с разноцветными мячиками. SELECT * FROM корзина — показать все мячики. WHERE цвет = 'красный' — показать только красные мячики.
В этом уроке мы разберём:
- Как работает WHERE
- Операторы сравнения: =, {'<', '>'}, {'<', '='}, {'>', '='}, {'<', '>'}
- Как сравнивать числа и текст
- Практические примеры на нашей базе данных
Только SELECT + WHERE. Никаких AND, OR, ORDER BY — это будет в следующем уроке.
Порядок слов в SQL-запросе строгий: сначала SELECT, потом FROM, потом WHERE. Нельзя написать WHERE перед FROM. Запомни порядок: SELECT → FROM → WHERE. Как в предложении: "Выбери (SELECT) из (FROM) таблицы employees где (WHERE) зарплата больше 80000".
🔧 WHERE — покажи только подходящие строки
Синтаксис WHERE очень простой. После FROM пишешь WHERE, а потом — условие:
SELECT * FROM employees WHERE salary > 80000; Этот запрос покажет только тех сотрудников, у которых зарплата БОЛЬШЕ 80000. Давай выполним и посмотрим на результат:
Должны увидеть:
- Мария Иванова — 95000 (разработчик, IT)
- Алексей Волков — 100000 (разработчик, IT)
Всего 2 строки вместо 10. WHERE сработал как фильтр: он пропустил только те строки, где значение в столбце salary больше 80000.
А теперь запрос, который показывает сотрудников с зарплатой ровно 80000:
SELECT * FROM employees WHERE salary = 80000; Результат: Иван Петров, Менеджер, Продажи, 80000.
Обрати внимание: для сравнения используется ОДИН знак равно (=), а не два (==), как в некоторых языках программирования. В SQL один знак = — это сравнение (а не присваивание).
Путают SELECT и WHERE. SELECT — это какие столбцы показать. WHERE — это какие строки оставить. Запомни: SELECT отвечает на вопрос "ЧТО показать?", WHERE — "КАКИЕ строки?". Это разные вещи. Можно показать только один столбец (SELECT name ...) и отфильтровать по другому (WHERE salary > 80000).
🔢 Операторы сравнения
В WHERE можно использовать разные операторы сравнения. Вот полный список:
| Оператор | Что значит | Пример |
|---|---|---|
= | Равно | WHERE salary = 80000 |
{'<', '>'} | Не равно | WHERE salary {'<', '>'} 80000 |
{'<', ''} | Меньше | WHERE salary < 80000 |
{'>', ''} | Больше | WHERE salary > 80000 |
{'<', '=', ''} | Меньше или равно | WHERE salary {'<=', ''} 80000 |
{'>=', ''} | Больше или равно | WHERE salary >= 80000 |
Все эти операторы работают как с числами, так и с текстом (для текста сравнение идёт по алфавиту).
Давай посмотрим примеры на каждое сравнение:
-- Равно: сотрудники с зарплатой ровно 75000
SELECT name, salary FROM employees WHERE salary = 75000; -- Не равно: все сотрудники, кроме отдела IT
SELECT name, department FROM employees WHERE department <> 'IT'; -- Меньше: товары дешевле 5000 рублей
SELECT name, price FROM products WHERE price < 5000; -- Больше: сотрудники старше 40 лет
SELECT name, age FROM employees WHERE age > 40; -- Меньше или равно: товары по цене не больше 2500
SELECT name, price FROM products WHERE price <= 2500; -- Больше или равно: сотрудники не моложе 35
SELECT name, age FROM employees WHERE age >= 35; Выполни каждый из этих запросов и посмотри на результаты. Обрати внимание на различия.
Разница между <, <=, >, >=
Это важно понять:
WHERE age > 35— возраст СТРОГО больше 35 (36, 37, ...). 35 не подходит.WHERE age >= 35— возраст 35 и больше (35, 36, 37, ...). 35 подходит.WHERE age < 35— возраст СТРОГО меньше 35 (34, 33, ...). 35 не подходит.WHERE age <= 35— возраст 35 и меньше (35, 34, 33, ...). 35 подходит.
Разница в том, включается ли граничное значение. Запомнить просто: = в <= и >= означает "включительно".
Не равно можно писать двумя способами: <> (во всех СУБД) или != (в некоторых, включая SQLite). Я рекомендую <> — это стандарт SQL. Но если встретишь != — знай, что это то же самое.
📝 Текст в кавычках
Когда мы сравниваем текстовые значения (столбцы типа TEXT), их нужно писать в кавычках. В SQLite и большинстве СУБД можно использовать как одинарные ('), так и двойные (") кавычки, но стандарт SQL предписывает одинарные для текста.
-- Сотрудники из отдела IT
SELECT name, department FROM employees WHERE department = 'IT'; -- Сотрудники с должностью "Менеджер"
SELECT name, position FROM employees WHERE position = 'Менеджер'; -- Клиенты из Москвы
SELECT name, city FROM customers WHERE city = 'Москва'; Важные правила для текста в WHERE:
- Кавычки ОБЯЗАТЕЛЬНЫ.
WHERE city = Москва— ошибка! SQLite решит, что "Москва" — это название столбца, не найдёт такой столбец и выдаст ошибку. - Регистр букв имеет значение. 'Москва' и 'москва' — разные значения. В SQLite сравнение текста по умолчанию регистрозависимое. То есть
WHERE city = 'москва'(с маленькой буквы) может ничего не найти, если в таблице написано 'Москва' (с большой). - Если в тексте есть кавычка внутри — её нужно удвоить:
WHERE name = 'Д''Артаньян'(две одинарные кавычки вместо одной).
Давай проверим регистрозависимость:
-- Найдёт клиентов из Москвы
SELECT name, city FROM customers WHERE city = 'Москва'; -- А это найдёт? (подсказка: нет)
SELECT name, city FROM customers WHERE city = 'москва'; Первый запрос вернёт 4 строки (все клиенты из Москвы). Второй — 0 строк, потому что 'москва' с маленькой буквы не совпадает с 'Москва' с большой. В реальной работе это важно помнить: если ты ищешь что-то, а запрос не находит — проверь регистр.
Забыть кавычки для текста. Если ты видишь ошибку "no such column: Москва" — значит, ты написал WHERE city = Москва без кавычек. SQLite думает, что Москва — это название столбца, и не может его найти. Исправление: добавь кавычки: WHERE city = 'Москва'.
🎯 Комбинируем SELECT и WHERE
Помни: SELECT выбирает столбцы, а WHERE фильтрует строки. Их можно комбинировать как угодно. Вот несколько примеров:
-- Показать только ИМЕНА сотрудников из отдела IT
SELECT name FROM employees WHERE department = 'IT'; -- Показать НАЗВАНИЕ и ЦЕНУ товаров дороже 20000
SELECT name, price FROM products WHERE price > 20000; -- Показать ВСЕ данные о клиентах старше 30
SELECT * FROM customers WHERE age > 30; -- Показать только ГОРОДА клиентов (без имён), старше 35 лет
SELECT city FROM customers WHERE age >= 35; -- Показать НАЗВАНИЕ и КОЛИЧЕСТВО товаров с ценой ровно 2500
SELECT name, quantity FROM products WHERE price = 2500; Обрати внимание: столбец, по которому мы фильтруем (например, price), не обязательно должен быть в SELECT. Ты можешь фильтровать по зарплате, а показывать только имена. Это нормально и часто используется.
Давай разберём подробнее:
- SELECT name FROM employees WHERE department = 'IT' — покажи имена (name) из строк, где отдел (department) равен 'IT'. Столбец department не попадает в результат, но используется для фильтрации.
- SELECT * FROM customers WHERE age > 30 — покажи ВСЁ про клиентов, которым больше 30 лет.
- SELECT city FROM customers WHERE age >= 35 — покажи только города клиентов 35+ лет. Имена клиентов не показываем, только города.
🔬 Подробный разбор примеров
Давай выполним несколько запросов с WHERE и тщательно разберём каждый. Запускай их по очереди и смотри на результат.
Пример 1: Все товары категории "Электроника"
SELECT * FROM products WHERE category = 'Электроника';
Результат: 3 товара (Ноутбук, Смартфон, Монитор). Все с category = 'Электроника'.
Пример 2: Сотрудники, которые НЕ из отдела Продажи
SELECT name, department FROM employees WHERE department <> 'Продажи';
Результат: 8 сотрудников (все, кроме Ивана Петрова и Николая Морозова, которые работают в Продажах).
Пример 3: Товары с ценой от 10000 до 30000 (включительно)
Сейчас мы не можем сделать "от и до" в одном условии (это будет в уроке 2.3 с AND). Но можно сделать два отдельных запроса:
-- Больше или равно 10000
SELECT name, price FROM products WHERE price >= 10000; -- Меньше или равно 30000
SELECT name, price FROM products WHERE price <= 30000;
Первый покажет 6 товаров (все от 10000 и выше). Второй — 6 товаров (все до 30000 включительно). Но пересечение этих множеств — товары от 10000 до 30000 — мы получим только в следующем уроке с помощью AND.
Пример 4: Клиенты с бонусами ровно 500
SELECT name, bonus FROM customers WHERE bonus = 500;
Результат: Иван Петров с бонусом 500.
Пример 5: Сотрудники младше 30 лет
SELECT name, age FROM employees WHERE age < 30;
Результат: Мария Иванова (28), Дмитрий Новиков (26), Николай Морозов (29). Все младше 30.
Пример 6: Товары, которых на складе больше 50 штук
SELECT name, quantity FROM products WHERE quantity > 50;
Результат: Наушники (100), Мышь (80), Лампа (60).
Пример 7: Сотрудники с зарплатой НЕ равной 65000
SELECT name, salary FROM employees WHERE salary <> 65000;
Результат: 9 сотрудников (все, кроме Анны Кузнецовой с зарплатой 65000).
Пример 8: Показать товары, у которых количество меньше 20
SELECT name, quantity FROM products WHERE quantity < 20;
Результат: Ноутбук (15), Принтер (10).
Попробуй намеренно сделать ошибку: напиши SELECT * FROM employees WHERE salary = '80000'. Сравниваешь число с текстом в кавычках. В SQLite это сработает (он сам преобразует), но в других СУБД может не сработать. Для чисел — без кавычек, для текста — с кавычками. Это правило нужно запомнить.
🔗 WHERE с разными типами данных
Давай посмотрим, как WHERE работает с разными типами столбцов в нашей таблице. Это поможет тебе не путаться в будущем.
INTEGER (целые числа): возраст, зарплата, количество товаров, бонусы, id.
-- Возраст (INTEGER)
SELECT name, age FROM employees WHERE age >= 35; -- Зарплата (INTEGER)
SELECT name, salary FROM employees WHERE salary < 70000; -- id (INTEGER) — тоже число
SELECT name FROM employees WHERE id = 5; TEXT (текст): имя, должность, отдел, название товара, категория, город.
-- Имя (TEXT)
SELECT * FROM employees WHERE name = 'Анна Кузнецова'; -- Категория (TEXT)
SELECT * FROM products WHERE category = 'Офис'; -- Город (TEXT)
SELECT name, city FROM customers WHERE city = 'Санкт-Петербург'; REAL (дробные числа): цена товаров.
-- Цена (REAL)
SELECT name, price FROM products WHERE price > 20000.00; -- Можно писать и без дробной части
SELECT name, price FROM products WHERE price > 20000; NULL (пустое значение): специальное значение, которое означает "нет данных". В наших таблицах нет NULL, но в реальной жизни они встречаются часто. Для проверки на NULL используется специальный синтаксис — не = NULL, а IS NULL:
-- Так не работает (даже если есть NULL)
SELECT * FROM employees WHERE department = NULL; -- Ничего не найдёт! -- Так работает
SELECT * FROM employees WHERE department IS NULL; -- Обратная проверка: NOT NULL
SELECT * FROM employees WHERE department IS NOT NULL; Запомни: с NULL нельзя использовать обычные операторы сравнения. Только IS NULL и IS NOT NULL. Это особенность SQL, которую нужно запомнить. Даже NULL = NULL — это не TRUE, а UNKNOWN (неизвестно), поэтому строка не попадёт в результат.
NULL — это не ноль и не пустая строка. Это "неизвестно", "нет данных". Сравнивать NULL с чем-либо через =, {'<', '>'} — бесполезно, результат всегда будет FALSE (точнее, UNKNOWN). Для проверки на NULL используй ТОЛЬКО IS NULL и IS NOT NULL. Запомни это раз и навсегда, это одна из самых частых ошибок начинающих.
🔎 LIKE — поиск по шаблону
Иногда нужно найти строки не по точному совпадению, а по части текста. Например, все товары, название которых НАЧИНАЕТСЯ с буквы «Н». Для этого используется оператор LIKE вместо =.
-- Все товары, название которых начинается с "Н"
SELECT * FROM products WHERE name LIKE 'Н%'; -- Все товары, название которых заканчивается на "ик"
SELECT * FROM products WHERE name LIKE '%ик'; -- Все товары, где встречается "теле" где угодно
SELECT * FROM products WHERE name LIKE '%теле%'; В шаблоне LIKE используются два спецсимвола:
%— любая последовательность символов (даже пустая).'Н%'— начинается с «Н»,'%ик'— заканчивается на «ик»,'%теле%'— содержит «теле» где угодно в строке._(нижнее подчёркивание) — ровно ОДИН любой символ.'Ф_ру'найдёт «Фару», «Фиру» и т.п., но не «Фаару».
LIKE, как и обычное сравнение текста, пишется с кавычками: WHERE name LIKE 'Н%'. В SQLite поиск через LIKE по умолчанию регистронезависимый для латиницы, но для кириллицы (русских букв) — регистрозависимый, так что 'н%' и 'Н%' для русского текста могут дать разные результаты.
🧪 Распространённые ошибки с WHERE
Давай разберём типичные ошибки, которые делают новички, чтобы ты их не повторял:
Ошибка 1: Забыли WHERE и получили все строки
-- Хотели только IT, а получили всех
SELECT name, department FROM employees;
Без WHERE фильтра нет — получаешь все строки. Если твой результат слишком большой — проверь, не забыл ли ты WHERE.
Ошибка 2: Двойной знак равенства
-- В некоторых языках ==, но в SQL надо =
SELECT name FROM employees WHERE salary == 80000; -- Ошибка!
В SQL сравнение выполняется с одним знаком =. Два знака == не работают (в большинстве СУБД это ошибка).
Ошибка 3: Не те кавычки
-- Для текста нужны кавычки
SELECT name FROM employees WHERE department = IT; -- Ошибка!
SQLite думает, что IT — это имя столбца, и не находит его. Правильно: WHERE department = 'IT'.
Ошибка 4: Несоответствие регистра
-- В таблице 'Москва', а ищем 'москва'
SELECT name FROM customers WHERE city = 'москва'; -- 0 результатов!
Не найдёт. В SQLite сравнение регистрозависимо. Нужно писать точно так, как в таблице.
Ошибка 5: Точка с запятой внутри запроса
-- Не ставь ; внутри запроса!
SELECT name; FROM employees WHERE salary > 50000; -- Ошибка!
Точка с запятой — только в конце запроса. Внутри неё быть не должно.
🎯 Практические задания
Выполни задания, используя учебную базу данных. Каждый запрос проверь на практике.
Задание 1: Найди всех сотрудников старше 30 лет. Выведи их имена и возраст.
-- Подсказка: используй WHERE age > 30 Задание 2: Найди все товары дороже 1000 рублей. Выведи название и цену. Сколько строк получилось?
Задание 3: Найди всех клиентов из Москвы. Выведи их имена и возраст.
Задание 4: Найди сотрудников, которые НЕ работают в отделе IT. Выведи имена и отделы.
Задание 5: Найди товары, которых на складе ровно 50 штук. Выведи название и количество.
Задание 6: Найди сотрудников с зарплатой меньше 60000. Выведи имена и зарплаты.
Задание 7: Найди клиентов младше 30 лет (строго меньше 30). Выведи имена и возраст.
Задание 8: Найди товары с ценой, которая НЕ РАВНА 1500. Выведи название и цену.
Задание 9: Выведи имена и бонусы клиентов, у которых бонус больше или равен 500.
Задание 10: Найди сотрудников с должностью 'Аналитик'. Выведи все данные о них.
Задание 11: Выведи названия товаров, у которых количество на складе меньше или равно 15. Сколько товаров подходит?
Задание 12: Найди клиентов с бонусом НЕ РАВНЫМ 300. Выведи имена и бонусы. Сколько их?
Задание 13: Выведи все данные о товаре с названием 'Монитор'. Сколько столбцов ты получил?
Задание 14: Найди сотрудников, которые НЕ являются Разработчиками (position {'<', '>'} 'Разработчик'). Сколько их?
Задание 15: Выведи имена и зарплаты сотрудников с зарплатой больше или равной 75000. Отсортируй по убыванию зарплаты (мы ещё не проходили ORDER BY, просто посмотри на результат).
После выполнения заданий проверь количество строк в результатах. Если ты ожидал 3 строки, а получил 10 — скорее всего, ты забыл WHERE. Если получил 0 — проверь регистр текста и кавычки. Если получил ошибку — прочитай её текст, в нём обычно написано, что не так.
🧠 Как думать в WHERE
WHERE — это фильтр. Он применяется к каждой строке таблицы по отдельности. Для каждой строки SQL проверяет условие: если оно истинно (TRUE), строка попадает в результат. Если ложно (FALSE) — отбрасывается.
Например, запрос SELECT * FROM employees WHERE salary > 80000; работает так:
- Берёт строку 1 (Иван Петров, salary=80000). Проверка: 80000 > 80000? НЕТ. Строка отбрасывается.
- Берёт строку 2 (Мария Иванова, salary=95000). Проверка: 95000 > 80000? ДА. Строка попадает в результат.
- И так для каждой строки из 10.
В результате получаем только строки, где условие истинно.
Это называется "горизонтальная фильтрация" — мы отсекаем целые строки. В отличие от SELECT, который делает "вертикальную фильтрацию" — выбирает только нужные столбцы.
Если представить таблицу как прямоугольник:
- SELECT выбирает столбцы (вертикаль)
- WHERE выбирает строки (горизонталь)
- Вместе они вырезают нужный кусок данных
Эта аналогия очень полезная. Держи её в голове, когда пишешь запросы.
📝 Что мы узнали в этом уроке
Подведём итоги урока 2.2:
- WHERE — фильтрует строки по условию. Пишется после FROM.
- Порядок в запросе: SELECT → FROM → WHERE. Нельзя нарушать.
- Операторы сравнения:
=(равно),<>(не равно),<(меньше),>(больше),<=(меньше или равно),>=(больше или равно). LIKE— поиск по шаблону текста, с%(любая последовательность символов) и_(один любой символ).- Для NULL — только
IS NULL/IS NOT NULL, обычные операторы (=,<>) с NULL не работают. - Числа пишутся без кавычек:
WHERE salary > 80000. - Текст пишется в одинарных кавычках:
WHERE city = 'Москва'. - Регистр текста имеет значение: 'Москва' и 'москва' — разные значения.
- Столбец в WHERE не обязан быть в SELECT. Можно фильтровать по одному столбцу, а показывать другой.
- WHERE проверяет каждую строку таблицы. Если условие истинно — строка попадает в результат.
Ты научился фильтровать данные. Это огромный шаг вперёд. Теперь ты можешь не просто смотреть на таблицы, но и находить в них нужную информацию. В следующем уроке мы добавим AND, OR и ORDER BY — и твои запросы станут ещё мощнее.
Увидимся в уроке 2.3! 👋
ТЕСТ — Урок 2.2: WHERE — фильтруем строки
5 вопросов