WHERE — это фильтр для строк. Без него запрос вернёт всё подряд, что есть в таблице. С ним — только то, что нужно.
Представь, что таблица — это шкаф с одеждой. Запрос SELECT * FROM clothes — это «дай мне всё, что есть». А SELECT * FROM clothes WHERE color = 'red' — «дай мне только красную одежду». WHERE — это и есть тот самый фильтр.
Зачем нужен WHERE
В реальных таблицах десятки тысяч (а то и миллионы) строк. Возвращать их все — это:
- Долго: база работает дольше, сеть передаёт больше данных.
- Бесполезно: тебе нужны конкретные пользователи, заказы или товары — а не вся таблица.
WHERE отсекает лишнее на стороне базы данных, до того как данные приедут к тебе. Это базовый инструмент любого SQL-разработчика и аналитика — без него никуда.
Как это работает в голове БД
Когда ты пишешь SELECT ... FROM users WHERE age > 18, база делает простую штуку:
- Берёт каждую строку из
users по очереди.
- Подставляет значение
age из этой строки в условие age > 18.
- Если получилось
TRUE — строка попадает в результат. Если FALSE — выбрасывается.
По сути, WHERE — это просто проверка «правда или нет?» для каждой строки.
Базовый синтаксис
SELECT name, age
FROM users
WHERE age > 18;
Что тут происходит, по строчкам:
SELECT name, age — какие колонки нам нужны.
FROM users — из какой таблицы тащим.
WHERE age > 18 — какие строки оставляем (только тех, кому больше 18).
Результат — список взрослых пользователей, причём только их имена и возраст (без email, телефона и прочего, чего мы не просили).
Какие условия можно писать
1. Сравнения
= — равно
<> или != — не равно
>, <, >=, <= — больше, меньше и комбинации с равно
SELECT * FROM products WHERE price > 1000;
SELECT * FROM users WHERE country = 'Russia';
SELECT * FROM orders WHERE status <> 'cancelled';
Пример с таблицей. Есть products:
| id |
name |
price |
| 1 |
Кружка |
350 |
| 2 |
Чайник |
1200 |
| 3 |
Микроволновка |
5000 |
| 4 |
Ложка |
80 |
Запрос:
SELECT name, price FROM products WHERE price > 1000;
Результат:
| name |
price |
| Чайник |
1200 |
| Микроволновка |
5000 |
Кружка и ложка отсеялись — у них цена меньше 1000.
2. Логические операторы AND, OR, NOT
AND — оба условия должны быть истинны
OR — достаточно, чтобы хотя бы одно было истинно
NOT — отрицание условия
SELECT * FROM users
WHERE country = 'Russia' AND age >= 21;
SELECT * FROM orders
WHERE status = 'paid' OR status = 'shipped';
SELECT * FROM products
WHERE NOT in_stock;
Пример «и/или» на пальцах. Таблица users:
| id |
name |
country |
age |
| 1 |
Аня |
Russia |
25 |
| 2 |
Боб |
USA |
30 |
| 3 |
Вера |
Russia |
17 |
| 4 |
Гриша |
Russia |
40 |
Запрос с AND (оба условия):
SELECT name FROM users WHERE country = 'Russia' AND age >= 21;
Результат:
Вера выпала — ей 17 (< 21). Боб — он не из России. Только Аня и Гриша подходят сразу под оба условия.
Тот же запрос с OR (хотя бы одно):
SELECT name FROM users WHERE country = 'Russia' OR age >= 21;
Результат:
Теперь подходят все четверо. Аня, Вера и Гриша — потому что Россия. Боб — потому что 30 лет (≥ 21). Хотя бы одно условие истинно у каждого.
3. Список значений: IN
Когда нужно проверить, входит ли значение в один из вариантов:
SELECT * FROM users
WHERE country IN ('Russia', 'Belarus', 'Kazakhstan');
Это короткая запись для:
WHERE country = 'Russia' OR country = 'Belarus' OR country = 'Kazakhstan'
IN читается легче, особенно если вариантов много.
Есть и обратная форма — NOT IN:
SELECT * FROM users WHERE country NOT IN ('USA', 'Canada');
4. Диапазон: BETWEEN
Удобно для дат, чисел и всего, что можно сравнивать.
SELECT * FROM orders
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31';
SELECT * FROM products
WHERE price BETWEEN 100 AND 500;
Важно: BETWEEN включает обе границы. То есть BETWEEN 100 AND 500 — это >= 100 AND <= 500. Цена ровно 100 и ровно 500 тоже попадут в результат.
5. Поиск по тексту: LIKE
Для частичного совпадения по строке:
SELECT * FROM users WHERE email LIKE '%@gmail.com';
SELECT * FROM users WHERE name LIKE 'А%';
SELECT * FROM users WHERE name LIKE '%нн%';
Два спецсимвола в LIKE:
% — любое количество любых символов (включая ноль)
_ — ровно один любой символ
Пример с _: WHERE phone LIKE '+7 9__' — все номера, начинающиеся на +7 9 и потом ещё ровно две цифры.
6. Проверка на NULL — отдельно от всего
Это самая частая ловушка для новичков. NULL в SQL — это не значение, а отсутствие значения. «Неизвестно». «Не заполнили».
И его нельзя сравнивать через =. Вообще никак. Даже сам с собой NULL = NULL даёт не TRUE, а опять NULL (вроде как «неизвестно равно неизвестному — хз»).
SELECT * FROM users WHERE deleted_at = NULL;
SELECT * FROM users WHERE deleted_at IS NULL;
SELECT * FROM users WHERE deleted_at IS NOT NULL;
Запомни: для NULL — только IS NULL и IS NOT NULL, никаких = или <>.
Большой пример: «до и после»
Есть таблица заказов orders:
| id |
user_id |
amount |
status |
country |
| 1 |
10 |
500 |
paid |
Russia |
| 2 |
11 |
1500 |
paid |
USA |
| 3 |
12 |
200 |
cancelled |
Russia |
| 4 |
13 |
3000 |
paid |
Russia |
| 5 |
14 |
800 |
pending |
Russia |
| 6 |
15 |
4500 |
paid |
Belarus |
Задача: «оплаченные заказы из России на сумму больше 1000».
Запрос:
SELECT id, amount
FROM orders
WHERE status = 'paid'
AND country = 'Russia'
AND amount > 1000;
Результат:
Кто отвалился и почему:
- №1: оплачен и из России, но сумма 500 — не подходит по
amount > 1000.
- №2: оплачен и сумма ОК, но США — не Россия.
- №3: cancelled — не paid.
- №5: pending — не paid.
- №6: оплачен и сумма ОК, но Беларусь — не Россия.
Остался только №4 — по нему сошлись все три условия одновременно (AND).
Теперь поменяем AND на OR для того же набора данных:
SELECT id, amount, country, status
FROM orders
WHERE status = 'paid'
OR country = 'Russia'
OR amount > 1000;
Результат:
| id |
amount |
country |
status |
| 1 |
500 |
Russia |
paid |
| 2 |
1500 |
USA |
paid |
| 3 |
200 |
Russia |
cancelled |
| 4 |
3000 |
Russia |
paid |
| 5 |
800 |
Russia |
pending |
| 6 |
4500 |
Belarus |
paid |
Попали все шесть, потому что у каждой строки нашлось хотя бы одно истинное условие из трёх. Отрезвляющая разница между AND и OR.
Ещё один пример: даты и текст
Та же таблица orders, но теперь с датами:
Задача: «заказы за 2024 год от пользователей с почтой на gmail».
SELECT id, email, amount
FROM orders
WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31'
AND email LIKE '%@gmail.com';
Результат:
Заказ №2 выпал — почта на yandex.ru, не gmail. №4 — за 2025 год, не за 2024.
Частые ошибки новичков
1. Сравнение NULL через =. Не работает никогда. Используй IS NULL и IS NOT NULL.
2. Кавычки в строках. Строки и даты — в одинарные кавычки '...'. Числа — без кавычек. Двойные кавычки "..." в PostgreSQL — это для имён колонок, а не для текста.
WHERE name = 'Alice' AND age = 30
WHERE name = "Alice"
3. Путаница AND и OR. В сложных условиях обязательно расставляй скобки, чтобы не угадывать приоритет:
WHERE country = 'Russia'
AND ((sex = 'M' AND age > 21) OR (sex = 'F' AND age > 18));
Без скобок логика может сработать совсем не так, как ты думаешь.
4. Фильтрация агрегатов через WHERE. Так нельзя. WHERE отрабатывает до группировки и не знает про COUNT, SUM и так далее. Для условий на агрегаты есть отдельный HAVING.
SELECT country, COUNT(*) FROM users
GROUP BY country
WHERE COUNT(*) > 100;
SELECT country, COUNT(*) FROM users
GROUP BY country
HAVING COUNT(*) > 100;
5. Регистр строк. WHERE name = 'Alice' и WHERE name = 'alice' — это разные условия в большинстве баз. Если регистр не важен, приведи обе стороны к одному:
WHERE LOWER(name) = 'alice'
6. Забытая запятая или AND. Если перечисляешь условия — между ними обязательно оператор AND или OR. Без него — ошибка синтаксиса.
WHERE country = 'Russia' age > 21
WHERE country = 'Russia' AND age > 21
Мини-резюме
WHERE фильтрует строки в SELECT, UPDATE, DELETE.
- Условия — сравнения,
AND/OR/NOT, IN, BETWEEN, LIKE.
- Для NULL — только
IS NULL / IS NOT NULL. Обычные сравнения с NULL молча не работают.
- Чем точнее условие, тем меньше данных база отдаёт — это и быстро, и удобно.
- Скобки в сложных условиях с
AND/OR — твой друг. Не угадывай приоритет, ставь явно.
WHERE— это фильтр для строк. Без него запрос вернёт всё подряд, что есть в таблице. С ним — только то, что нужно.Представь, что таблица — это шкаф с одеждой. Запрос
SELECT * FROM clothes— это «дай мне всё, что есть». АSELECT * FROM clothes WHERE color = 'red'— «дай мне только красную одежду».WHERE— это и есть тот самый фильтр.Зачем нужен WHERE
В реальных таблицах десятки тысяч (а то и миллионы) строк. Возвращать их все — это:
WHEREотсекает лишнее на стороне базы данных, до того как данные приедут к тебе. Это базовый инструмент любого SQL-разработчика и аналитика — без него никуда.Как это работает в голове БД
Когда ты пишешь
SELECT ... FROM users WHERE age > 18, база делает простую штуку:usersпо очереди.ageиз этой строки в условиеage > 18.TRUE— строка попадает в результат. ЕслиFALSE— выбрасывается.По сути,
WHERE— это просто проверка «правда или нет?» для каждой строки.Базовый синтаксис
SELECT name, age FROM users WHERE age > 18;Что тут происходит, по строчкам:
SELECT name, age— какие колонки нам нужны.FROM users— из какой таблицы тащим.WHERE age > 18— какие строки оставляем (только тех, кому больше 18).Результат — список взрослых пользователей, причём только их имена и возраст (без email, телефона и прочего, чего мы не просили).
Какие условия можно писать
1. Сравнения
=— равно<>или!=— не равно>,<,>=,<=— больше, меньше и комбинации с равноSELECT * FROM products WHERE price > 1000; SELECT * FROM users WHERE country = 'Russia'; SELECT * FROM orders WHERE status <> 'cancelled';Пример с таблицей. Есть
products:Запрос:
SELECT name, price FROM products WHERE price > 1000;Результат:
Кружка и ложка отсеялись — у них цена меньше 1000.
2. Логические операторы AND, OR, NOT
AND— оба условия должны быть истинныOR— достаточно, чтобы хотя бы одно было истинноNOT— отрицание условияSELECT * FROM users WHERE country = 'Russia' AND age >= 21; SELECT * FROM orders WHERE status = 'paid' OR status = 'shipped'; SELECT * FROM products WHERE NOT in_stock;Пример «и/или» на пальцах. Таблица
users:Запрос с
AND(оба условия):SELECT name FROM users WHERE country = 'Russia' AND age >= 21;Результат:
Вера выпала — ей 17 (< 21). Боб — он не из России. Только Аня и Гриша подходят сразу под оба условия.
Тот же запрос с
OR(хотя бы одно):SELECT name FROM users WHERE country = 'Russia' OR age >= 21;Результат:
Теперь подходят все четверо. Аня, Вера и Гриша — потому что Россия. Боб — потому что 30 лет (≥ 21). Хотя бы одно условие истинно у каждого.
3. Список значений: IN
Когда нужно проверить, входит ли значение в один из вариантов:
SELECT * FROM users WHERE country IN ('Russia', 'Belarus', 'Kazakhstan');Это короткая запись для:
WHERE country = 'Russia' OR country = 'Belarus' OR country = 'Kazakhstan'INчитается легче, особенно если вариантов много.Есть и обратная форма —
NOT IN:SELECT * FROM users WHERE country NOT IN ('USA', 'Canada');4. Диапазон: BETWEEN
Удобно для дат, чисел и всего, что можно сравнивать.
SELECT * FROM orders WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31'; SELECT * FROM products WHERE price BETWEEN 100 AND 500;Важно:
BETWEENвключает обе границы. То естьBETWEEN 100 AND 500— это>= 100 AND <= 500. Цена ровно 100 и ровно 500 тоже попадут в результат.5. Поиск по тексту: LIKE
Для частичного совпадения по строке:
-- Все, у кого почта на gmail SELECT * FROM users WHERE email LIKE '%@gmail.com'; -- Все, чьё имя начинается на 'А' SELECT * FROM users WHERE name LIKE 'А%'; -- Все, в чьём имени есть 'нн' SELECT * FROM users WHERE name LIKE '%нн%';Два спецсимвола в
LIKE:%— любое количество любых символов (включая ноль)_— ровно один любой символПример с
_:WHERE phone LIKE '+7 9__'— все номера, начинающиеся на +7 9 и потом ещё ровно две цифры.6. Проверка на NULL — отдельно от всего
Это самая частая ловушка для новичков.
NULLв SQL — это не значение, а отсутствие значения. «Неизвестно». «Не заполнили».И его нельзя сравнивать через
=. Вообще никак. Даже сам с собойNULL = NULLдаёт неTRUE, а опятьNULL(вроде как «неизвестно равно неизвестному — хз»).-- НЕПРАВИЛЬНО: ничего не вернёт, даже если в таблице есть NULL SELECT * FROM users WHERE deleted_at = NULL; -- ПРАВИЛЬНО SELECT * FROM users WHERE deleted_at IS NULL; SELECT * FROM users WHERE deleted_at IS NOT NULL;Запомни: для NULL — только
IS NULLиIS NOT NULL, никаких=или<>.Большой пример: «до и после»
Есть таблица заказов
orders:Задача: «оплаченные заказы из России на сумму больше 1000».
Запрос:
SELECT id, amount FROM orders WHERE status = 'paid' AND country = 'Russia' AND amount > 1000;Результат:
Кто отвалился и почему:
amount > 1000.Остался только №4 — по нему сошлись все три условия одновременно (
AND).Теперь поменяем
ANDнаORдля того же набора данных:SELECT id, amount, country, status FROM orders WHERE status = 'paid' OR country = 'Russia' OR amount > 1000;Результат:
Попали все шесть, потому что у каждой строки нашлось хотя бы одно истинное условие из трёх. Отрезвляющая разница между
ANDиOR.Ещё один пример: даты и текст
Та же таблица
orders, но теперь с датами:Задача: «заказы за 2024 год от пользователей с почтой на gmail».
SELECT id, email, amount FROM orders WHERE created_at BETWEEN '2024-01-01' AND '2024-12-31' AND email LIKE '%@gmail.com';Результат:
Заказ №2 выпал — почта на yandex.ru, не gmail. №4 — за 2025 год, не за 2024.
Частые ошибки новичков
1. Сравнение NULL через
=. Не работает никогда. ИспользуйIS NULLиIS NOT NULL.2. Кавычки в строках. Строки и даты — в одинарные кавычки
'...'. Числа — без кавычек. Двойные кавычки"..."в PostgreSQL — это для имён колонок, а не для текста.-- Правильно WHERE name = 'Alice' AND age = 30 -- Неправильно WHERE name = "Alice" -- это будет искать колонку Alice, ошибка3. Путаница AND и OR. В сложных условиях обязательно расставляй скобки, чтобы не угадывать приоритет:
-- Хочется: страна Россия И (мужчины старше 21 ИЛИ женщины старше 18) WHERE country = 'Russia' AND ((sex = 'M' AND age > 21) OR (sex = 'F' AND age > 18));Без скобок логика может сработать совсем не так, как ты думаешь.
4. Фильтрация агрегатов через WHERE. Так нельзя.
WHEREотрабатывает до группировки и не знает проCOUNT,SUMи так далее. Для условий на агрегаты есть отдельныйHAVING.-- Неправильно SELECT country, COUNT(*) FROM users GROUP BY country WHERE COUNT(*) > 100; -- Правильно SELECT country, COUNT(*) FROM users GROUP BY country HAVING COUNT(*) > 100;5. Регистр строк.
WHERE name = 'Alice'иWHERE name = 'alice'— это разные условия в большинстве баз. Если регистр не важен, приведи обе стороны к одному:WHERE LOWER(name) = 'alice'6. Забытая запятая или AND. Если перечисляешь условия — между ними обязательно оператор
ANDилиOR. Без него — ошибка синтаксиса.-- Неправильно (нет AND) WHERE country = 'Russia' age > 21 -- Правильно WHERE country = 'Russia' AND age > 21Мини-резюме
WHEREфильтрует строки вSELECT,UPDATE,DELETE.AND/OR/NOT,IN,BETWEEN,LIKE.IS NULL/IS NOT NULL. Обычные сравнения с NULL молча не работают.AND/OR— твой друг. Не угадывай приоритет, ставь явно.