Введение
SELECT — основная команда извлечения данных из таблиц реляционной БД, и в статье разберём её базовый синтаксис: выбор конкретных столбцов, фильтрацию строк через WHERE, и сортировку результата через ORDER BY — фундамент, на котором строятся все более сложные запросы из последующих статей цикла.
Концепция
SELECT определяет, какие столбцы (или вычисляемые выражения) попадут в результат запроса — это не обязательно все столбцы таблицы (SELECT *, обычно нежелательный на практике способ, статья 422). WHERE фильтрует строки исходной таблицы до того, как они попадают в результат, на основе логического условия, проверяемого для каждой строки независимо. ORDER BY определяет порядок строк в итоговом результате — без него СУБД не гарантирует какой-либо конкретный, предсказуемый порядок строк (даже если на практике порядок часто кажется стабильным, это не гарантия, на которую стоит полагаться).
Пример кода: SELECT, WHERE, ORDER BY
-- Выбор конкретных столбцов с фильтрацией и сортировкой
SELECT name, email, registered_at
FROM customers
WHERE registered_at >= '2026-01-01'
ORDER BY registered_at DESC;
-- Комбинация условий через AND/OR, и операторы сравнения
SELECT name, total_amount
FROM orders
WHERE total_amount > 1000 AND order_date >= '2026-01-01'
ORDER BY total_amount DESC, order_date ASC;
-- LIKE для текстового поиска по шаблону, IN для проверки принадлежности набору значений
SELECT name, email
FROM customers
WHERE name LIKE 'Иван%' -- начинается с "Иван"
AND id IN (1, 5, 10, 15); -- id входит в явно перечисленный набор
-- LIMIT для ограничения количества возвращаемых строк (синтаксис варьируется между СУБД)
SELECT name, total_amount
FROM orders
ORDER BY total_amount DESC
LIMIT 10; -- топ-10 заказов по сумме
Пояснения к коду
Условие WHERE registered_at >= '2026-01-01' демонстрирует, что фильтрация происходит до агрегации или иной обработки — каждая строка таблицы customers независимо проверяется на соответствие этому условию, и только прошедшие проверку строки участвуют в дальнейшей обработке запроса (включая последующую сортировку через ORDER BY). ORDER BY total_amount DESC, order_date ASC показывает многоуровневую сортировку — сначала строки упорядочиваются по убыванию суммы заказа, и только строки с равным значением суммы дополнительно упорядочиваются по дате возрастания — это устраняет неоднозначность порядка строк с одинаковым значением первого критерия сортировки.
Подводные камни
- Использование
SELECT *в production-коде вместо явного перечисления нужных столбцов — помимо проблем с производительностью (статья 422),SELECT *делает запрос хрупким к изменениям схемы таблицы (добавление нового столбца в будущем неожиданно меняет структуру результата без изменения самого запроса) и затрудняет понимание того, какие данные запрос реально использует, при чтении кода спустя время. - Сравнение с NULL через обычный оператор равенства (
WHERE email = NULL) вместо специального синтаксисаIS NULL— NULL в SQL представляет «неизвестное» значение, а не просто «пустое», и сравнение чего-либо с NULL через=всегда даёт результат NULL (не TRUE и не FALSE), что означает, что строка никогда не пройдёт такой фильтр независимо от реального содержимого; эта особенность разбирается подробнее в статье 396. - Использование
LIKEс шаблоном, начинающимся с%(например,LIKE '%Петров'), без понимания, что это обычно не может использовать стандартный B-tree индекс (статья 413) эффективно, поскольку индекс упорядочен по началу строки, а не по произвольной её части — для частого поиска по такому «обратному» шаблону стоит рассмотреть специализированные индексы полнотекстового поиска (статья 441) вместо обычного индекса с обратнымLIKE. - Предположение об определённом, стабильном порядке строк результата без явного
ORDER BY— без явной сортировки СУБД вольна вернуть строки в любом порядке, который сочла удобным для своего текущего плана выполнения (статья 416), и хотя на практике для простых запросов порядок может казаться стабильным при многократном выполнении, это не гарантированное, документированное поведение, и код, зависящий от порядка строк без явногоORDER BY, может неожиданно «сломаться» при изменении версии СУБД, плана выполнения или просто объёма данных в таблице.