Мастер-чек: SELECT в деле
Чему научишься
- закрепишь умение собирать полный
SELECT: выбирать столбцы, давать , фильтровать строки, сортировать результат и ограничивать выдачу - повторишь основные фильтры модуля:
WHERE,BETWEEN,IN,LIKE,IS NULL,IS NOT NULL - закрепишь связку
ORDER BY ... LIMIT ...для топов и коротких отчётов - вспомнишь, когда нужен
DISTINCT, а когда лучше думать в сторону группировки - повторишь
CASEкак способ добавить в выдачу понятные метки - научишься внимательнее читать запросы, которые синтаксически верные, но логически дают не тот результат
- закрепишь привычки надёжного запроса: скобки в смешанных условиях, явный
ELSE, явная сортировка и аккуратная работа сNULL
Закрепим SELECT на реальных задачах
КВЕРИ гасит лишние панели. В зале остаются один терминал и три задачи: экзамен на первый допуск.
Академия не верит словам — только запросам.
За этот модуль ты собрал базовый набор архивиста-чтеца. Теперь ты умеешь не просто писать:
SELECT *
FROM products;
а задавать базе точный вопрос.
Ты выбираешь нужные столбцы:
SELECT name, price
FROM products;
Даёшь им понятные имена:
SELECT
name AS product_name,
price AS product_price
FROM products;
Оставляешь только нужные строки:
SELECT name, price
FROM products
WHERE price >= 1000;
Работаешь с отсутствующими значениями:
SELECT id, name, city
FROM users
WHERE city IS NULL;
Пишешь короткие фильтры через диапазоны, списки и шаблоны:
SELECT name, category, price
FROM products
WHERE category IN ('Книги', 'Игрушки')
AND price BETWEEN 1000 AND 3000
AND name LIKE 'К%';
Задаёшь порядок:
SELECT name, price
FROM products
ORDER BY price DESC;
Берёшь верхушку результата:
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 5;
Убираешь повторы, когда нужен словарь значений:
SELECT DISTINCT status
FROM orders;
И добавляешь простую логику прямо в выдачу:
SELECT
name,
price,
CASE
WHEN price < 1500 THEN 'дешёвый'
WHEN price < 4000 THEN 'средний'
ELSE 'дорогой'
END AS segment
FROM products;
Теперь всё это нужно собрать в голове как один инструмент.
Не отдельные команды.
Не набор случайных операторов.
А полный путь запроса: от таблицы к понятному результату.
КВЕРИ: Первый допуск получают не за знание слов. Его получают за точный вопрос к архиву.

Как читать полный SELECT
Когда запрос становится длиннее трёх строк, новичок часто теряется. Кажется, что SQL выполняется строго сверху вниз, как текст.
Но удобнее читать запрос по смысловым слоям.
Например:
SELECT
name,
category,
price,
CASE
WHEN price < 1500 THEN 'дешёвый'
WHEN price < 4000 THEN 'средний'
ELSE 'дорогой'
END AS segment
FROM products
WHERE category IN ('Книги', 'Игрушки')
AND price BETWEEN 1000 AND 3000
ORDER BY price DESC, id
LIMIT 5;
Такой запрос можно разобрать по шагам.
Сначала источник:
FROM products
База берёт таблицу товаров.
Потом фильтр строк:
WHERE category IN ('Книги', 'Игрушки')
AND price BETWEEN 1000 AND 3000
Остаются только книги и игрушки с ценой от 1000 до 3000 включительно.
Потом список столбцов и вычислений:
SELECT
name,
category,
price,
CASE ... END AS segment
Запрос показывает название, категорию, цену и добавляет сегмент через CASE.
Потом порядок:
ORDER BY price DESC, id
Сначала дорогие товары, а при одинаковой цене — стабильная сортировка по id.
И только после этого ограничение:
LIMIT 5
Остаются первые пять строк уже после сортировки.
Главная мысль:
LIMITне выбирает «лучшие» строки сам. Он просто берёт верхушку того порядка, который ты задал черезORDER BY.
Что делает запрос надёжным
На этом уровне важно не просто получить зелёную галочку. Важно начать думать как человек, который понимает, почему запрос вернул именно эти строки.
Надёжный запрос обычно обладает тремя признаками.
Первый признак — он явно говорит, какие строки нужны.
Плохо, когда условие приходится угадывать по куску логики. Хорошо, когда WHERE читается как точное правило:
WHERE category IN ('Книги', 'Игрушки')
AND price BETWEEN 1000 AND 3000
Второй признак — он явно говорит, в каком порядке нужен результат.
Если важны самые дорогие товары, самые свежие заказы или первые пользователи по алфавиту, это должно быть записано в ORDER BY:
ORDER BY price DESC, id
Третий признак — он не прячет неопределённость.
Если в данных может быть NULL, запрос должен учитывать это явно:
WHERE city IS NULL
или:
WHERE city <> 'Москва'
OR city IS NULL
Если в CASE есть строки, которые не попали ни в одну ветку, лучше заранее решить, что с ними делать:
ELSE 'другой статус'
Если порядок при равных значениях важен, его нужно добить уникальным ключом:
ORDER BY price DESC, id
На маленьких учебных таблицах многие недочёты незаметны. Но в реальной базе такие мелочи превращаются в тихие ошибки: запрос выполняется без падения, но результат оказывается не тем.
Тихие ошибки: когда запрос работает, но врёт
Самые неприятные ошибки в SQL не всегда выглядят как красная ошибка синтаксиса.
Гораздо чаще запрос запускается, возвращает таблицу, но строки в ней не те.
Например, сравнение с NULL:
WHERE city = NULL
Синтаксически запрос может быть корректным, но он не найдёт строки, где города нет. Для NULL нужна проверка:
WHERE city IS NULL
Или условие со смешанными AND и OR:
WHERE category = 'Книги'
OR category = 'Игрушки'
AND price < 3000
Такой запрос читается глазами как:
книги или игрушки, и цена меньше 3000
Но SQL сначала связывает AND, а потом OR. Поэтому фактическая логика другая:
WHERE category = 'Книги'
OR (category = 'Игрушки' AND price < 3000)
Если тебе нужно применить цену к обеим категориям, нужны скобки:
WHERE (category = 'Книги' OR category = 'Игрушки')
AND price < 3000
Или так, ещё чище:
WHERE category IN ('Книги', 'Игрушки')
AND price < 3000
Ещё один тихий сбой — CASE без ELSE:
CASE
WHEN status = 'paid' THEN 'оплачен'
WHEN status = 'pending' THEN 'ожидает'
END AS status_label
Если появится статус cancelled, метка станет NULL. Иногда это нормально, но чаще для отчёта лучше явно написать запасной вариант:
ELSE 'другой статус'
И наконец, LIMIT без ORDER BY:
SELECT name, price
FROM products
LIMIT 5;
Этот запрос не выбирает топ-5. Он выбирает любые первые пять строк в том порядке, который база решила вернуть сейчас.
Для топа нужен критерий:
SELECT name, price
FROM products
ORDER BY price DESC, id
LIMIT 5;
Тихие ошибки опасны именно тем, что база не спорит. Она выполняет то, что написано. Даже если ты имел в виду другое.
КВЕРИ: Архив не читает намерения. Он читает запрос. Если мысль не записана явно, её не существует.
Перед отправкой запроса
Перед тем как отправить решение в тренажёре, полезно быстро пройтись по запросу глазами.
Сначала проверь, что ты выбрал ровно нужные столбцы.
Если в задаче просят:
name, price
не нужно оставлять:
SELECT *
Даже если так проще во время черновика, финальный ответ должен показывать то, что просит задача.
Потом проверь фильтр.
Если в условии задачи есть «от 1000 до 3000 включительно», хорошо подходит:
BETWEEN 1000 AND 3000
Если сказано «категория Книги или Игрушки», читаемее использовать:
IN ('Книги', 'Игрушки')
Если нужно «начинается с», подойдёт:
LIKE 'К%'
Если нужно «содержит», подойдёт:
LIKE '%К%'
Но помни: ведущий % может быть дорогим на больших таблицах.
Потом проверь NULL.
Если нужно найти отсутствующее значение, не пиши:
= NULL
Пиши:
IS NULL
Если нужно исключить значение, но сохранить строки с NULL, добавь это явно:
WHERE city <> 'Москва'
OR city IS NULL
Потом проверь сортировку.
Если в задаче есть слова:
самые дорогие
самые дешёвые
последние
первые
топ
почти наверняка нужен ORDER BY.
Если есть ограничение количества строк, почти наверняка нужен LIMIT.
И наконец, если сортируешь по столбцу, где возможны одинаковые значения, добавь уникальный ключ:
ORDER BY price DESC, id
Так результат будет стабильным.
Что ты уже умеешь к концу модуля
Этот модуль был про чтение строк.
Ты ещё не считаешь выручку, средний чек и количество заказов по группам — это следующий уровень. Но ты уже умеешь достать из таблицы именно тот слой данных, который нужен для ответа.
Тебе доступен базовый маршрут:
SELECT ...
FROM ...
WHERE ...
ORDER BY ...
LIMIT ...
Ты понимаешь, зачем нужны :
price * stock AS stock_value
Ты умеешь работать с отсутствующими значениями:
IS NULL
IS NOT NULL
COALESCE(...)
Ты умеешь задавать короткие фильтры:
BETWEEN
IN
LIKE
Ты умеешь получать словарь значений:
SELECT DISTINCT status
FROM orders;
Ты умеешь добавлять в выдачу человеческие метки:
CASE
WHEN ... THEN ...
ELSE ...
END
И главное — ты уже знаешь, что корректный синтаксис не гарантирует корректную мысль.
SQL может выполнить запрос идеально и всё равно вернуть не то, что ты хотел, если условие записано неточно.
Вопрос с собеседования
Вопрос с собеседования:
Запрос синтаксически корректен, но строки незаметно пропадают из выдачи или получают не те значения. Назови типичные причины.
Сильный ответ:
Частая причина — неправильная работа с NULL. Сравнения через =, <> и некоторые варианты NOT IN, если там появляется NULL, могут дать UNKNOWN. А WHERE пропускает только TRUE, поэтому строки исчезают без ошибки. Для NULL нужны IS NULL, IS NOT NULL, иногда COALESCE или IS DISTINCT FROM в PostgreSQL.
Вторая причина — смешанные AND и OR без скобок. AND имеет более высокий приоритет, поэтому условие может сгруппироваться не так, как его прочитал человек. Если логика не очевидна, лучше поставить скобки явно.
Третья причина — неполный CASE. Если ни один WHEN не сработал и ELSE не написан, результатом будет NULL. А в простой форме CASE x WHEN NULL THEN ... ветка не сработает, потому что это сравнение через x = NULL.
Четвёртая причина — LIMIT без ORDER BY. Такой запрос возвращает не «первые по смыслу» строки, а просто некоторое количество строк в неопределённом порядке. Для топов и страниц нужен явный ORDER BY, а для стабильности при равных значениях — дополнительная сортировка по уникальному ключу.
На собеседовании важно не просто перечислить эти случаи, а показать привычку писать надёжно: явно проверять NULL, ставить скобки в смешанных условиях, добавлять ELSE в CASE и не использовать LIMIT как замену сортировке.
КВЕРИ: Дальше архив открывается только тем, кто считает. Выручка, средний чек, группы — следующий уровень допуска.