$ sudo teach IT

🔍 Урок 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 — это не ноль и не пустая строка. Это "неизвестно", "нет данных". Сравнивать 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. Берёт строку 1 (Иван Петров, salary=80000). Проверка: 80000 > 80000? НЕТ. Строка отбрасывается.
  2. Берёт строку 2 (Мария Иванова, salary=95000). Проверка: 95000 > 80000? ДА. Строка попадает в результат.
  3. И так для каждой строки из 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 вопросов

Фильтрация товаров по цене

Premium

Поиск товаров по шаблону названия

Premium