Это часть 2 из 10 учебника «SQL с нуля для аналитика». Содержание серии в конце поста. ← Часть 1
TL;DR: SELECT — главная команда чтения данных. FROM — откуда читать. WHERE — какие строки оставить. Минимальный запрос: SELECT col1, col2 FROM table WHERE condition. Операторы: =, <>, <, >, BETWEEN, IN, LIKE. Для NULL — IS NULL / IS NOT NULL. Логические связки: AND, OR, NOT.
В этой части:
- Базовый синтаксис SELECT
- Разница между
SELECT *и перечислением колонок - Все операторы WHERE
- Как фильтровать NULL
- Логические связки AND, OR, NOT и их приоритет
Как написать первый SQL-запрос?
Минимальный запрос — три ключевых слова:
SELECT email
FROM users;
Расшифровка:
- SELECT email — какие колонки вернуть
- FROM users — из какой таблицы
- ; — конец запроса
Результат: список всех email из таблицы users. Если строк миллион — вернёт миллион.
Например, типичный первый запрос на работе: SELECT COUNT(*) FROM orders WHERE created_at >= CURRENT_DATE - INTERVAL '1 day'; — сколько заказов за сутки. Простой, но реально нужен в каждом дашборде.
Чем отличается SELECT * от перечисления колонок?
SELECT * возвращает все колонки:
SELECT * FROM users;
-- id | email | created_at | last_login | preferences | ...
Перечисление — только нужные:
SELECT email, created_at FROM users;
-- email | created_at
**Аналитик почти никогда не пишет SELECT *. Причины:
- Возвращается больше данных = медленнее сеть + рендеринг
- Если в таблицу добавят колонку — запрос сломает что-то downstream
- Непонятно из кода, какие данные используются
Исключение**: research-режим в SQL Lab — посмотреть структуру таблицы. В production-запросах — никогда *.
Какие операторы есть в WHERE?
WHERE оставляет только строки, удовлетворяющие условию.
| Оператор | Пример | Что делает |
|---|---|---|
= | WHERE country = 'RU' | Равенство |
<> или != | WHERE status <> 'cancelled' | Не равно |
<, >, <=, >= | WHERE amount > 1000 | Сравнение чисел / дат |
BETWEEN | WHERE age BETWEEN 18 AND 65 | Включая границы |
IN | WHERE country IN ('RU', 'KZ', 'BY') | Любое из списка |
NOT IN | WHERE status NOT IN ('test', 'deleted') | Ни одно из списка |
LIKE | WHERE email LIKE '%@yandex.ru' | Поиск по подстроке |
IS NULL | WHERE deleted_at IS NULL | Только не удалённые |
Примеры:
-- Заказы дороже 1000 рублей в России
SELECT order_id, amount
FROM orders
WHERE country = 'RU' AND amount > 1000;
-- Email на yandex.ru или mail.ru
SELECT email
FROM users
WHERE email LIKE '%@yandex.ru' OR email LIKE '%@mail.ru';
-- Регистрации в 2026 году
SELECT user_id, created_at
FROM users
WHERE created_at >= '2026-01-01';
Как работать с NULL в WHERE?
NULL — особое значение «нет данных». Нельзя сравнивать через =:
-- НЕПРАВИЛЬНО (вернёт 0 строк, даже если есть deleted_at = 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 подробно разбираем в Части 7.
Типичный случай: разработчик добавил колонкуdeleted_atдля soft-delete. Аналитик пишетWHERE deleted_at != NULL— запрос возвращает 0 строк, никто не понимает почему. Правильно:WHERE deleted_at IS NULL.
Что такое AND OR NOT и какой приоритет?
Логические связки:
AND— оба условия trueOR— хотя бы одно trueNOT— отрицание
Приоритет: NOT > AND > OR. Используй скобки чтобы не путаться:
-- Без скобок (двоякое чтение)
WHERE country = 'RU' AND status = 'paid' OR amount > 10000
-- Со скобками (однозначно)
WHERE (country = 'RU' AND status = 'paid') OR amount > 10000
-- ИЛИ другой вариант
WHERE country = 'RU' AND (status = 'paid' OR amount > 10000)
Правило: всегда ставь скобки. Тогда и через 3 месяца ты сам поймёшь свой запрос.
Какие 5 ошибок новички делают в SELECT?
- Ошибка 1:
SELECT *в production. Фикс — перечисляй колонки. - Ошибка 2:
WHERE deleted_at = NULLвместоIS NULL. Всегда возвращает 0. - Ошибка 3: Забыли
;в конце. Зависит от клиента — иногда работает, иногда нет. - Ошибка 4: Кавычки. Строки — одинарные
'RU'. Двойные"name"— это идентификатор колонки. - Ошибка 5: Регистр в значениях.
WHERE country = 'ru'найдёт только нижний регистр. ИспользуйUPPER()илиILIKE.
Подробнее про антипаттерны — в нашем посте.
Например, классическая ошибка новичка: SELECT * FROM orders на таблице 10М строк — клиент BI ждёт 30 секунд, потом отваливается. Урок: всегда перечисляй колонки + LIMIT для exploration.
Частые вопросы про SELECT FROM WHERE
Можно ли SELECT без FROM?
Да, для тестов: SELECT 1 + 1; или SELECT NOW();. Реальные запросы всегда с FROM.
Зачем WHERE 1=1 в начале?
Удобно для конструирования запросов с динамическими фильтрами:
WHERE 1=1
AND country = 'RU'
AND status = 'paid'
Каждое условие можно закомментировать без сломанной логики. Распространённый паттерн в dbt и AdHoc-аналитике.
Какие случаи приемлемы для SELECT *?
Research/exploration: «дай первые 10 строк, посмотрю что есть». Подзапросы для EXISTS (SELECT * FROM ...). В CTE редкий случай — иногда читаемее.
Как написать «не равно»?
<> или != — оба работают в PostgreSQL. Стандарт ANSI — <>.
Что быстрее: WHERE a AND b или WHERE b AND a?
В современных PG/CH порядок не важен — оптимизатор сам выбирает. Раньше (MySQL 5.x) — да, влияло. Сейчас — нет.
Что дальше?
В Части 3 — сортировка результатов, ограничение количества строк, уникальные значения и пагинация.
Сейчас открой SQL-тренажёр и попробуй написать несколько SELECT-запросов с WHERE. Первые 5 задач бесплатны, идеально для практики этой части.
В Pro — безлимит мок-собесов на AI-интервью + 491 SQL-задача + 612 тестовых заданий + 50+ блог-постов.
Навигация по учебнику
← Часть 1 | Часть 2: SELECT FROM WHERE | Часть 3 →
Содержание серии:
- Что такое БД и SQL
- SELECT FROM WHERE (вы здесь)
- ORDER BY, LIMIT, DISTINCT
- Агрегаты + GROUP BY
- JOIN
- Подзапросы и CTE
- NULL, типы, CASE
- Дата и время
- Строки и текст
- Window Functions intro
Источники
- PostgreSQL Docs: «The SELECT command» (postgresql.org/docs/current/sql-select.html)
- PostgreSQL Docs: «Conditional Expressions» (postgresql.org/docs/current/functions-conditional.html)
- ANSI SQL standard reference