Медиаблог /

Что такое SQL-запросы: виды, примеры и синтаксис с объяснением

7 июля 2026

Что такое SQL-запросы: виды, примеры и синтаксис с объяснением

SQL-запросы — инструкции языка структурированных запросов (Structured Query Language) для управления реляционными базами данных. Стандарт SQL описан в ISO/IEC 9075 и применяется во всех крупных системах управления базами данных (СУБД): PostgreSQL, MySQL, Oracle, SQL Server.

Аналитик за монитором пишет SQL-запросы в офисе

По данным hh.ru, SQL входит в обязательные требования более чем в 80% вакансий для аналитиков данных. При этом порог входа невысок: синтаксис строится почти как предложение на английском — SELECT name FROM users WHERE age > 25.

image

Учитесь бесплатно за счёт государства

Экономия до 100 000 ₽ на любой программе

Выбрать курс

В этой статье собраны sql запросы примеры всех уровней сложности: от минимального SELECT * до оконных функций с OVER (PARTITION BY). Разберём базовый синтаксис и порядок выполнения команд, затем GROUP BY и JOIN, подзапросы, обобщённые табличные выражения (CTE, Common Table Expressions) и оконные функции. В конце — типовые паттерны аналитика и частые ошибки начинающих.

Что такое SQL-запросы: определение и назначение

Схема реляционной базы данных с таблицами customers orders products

Язык структурированных запросов создан в 1974 году в лаборатории IBM Research. В 1986 году принят стандартом ANSI, с 1987-го — стандартом ISO/IEC 9075. Сегодня он реализован в десятках СУБД: реляционных (PostgreSQL, MySQL, Oracle, SQL Server) и аналитических (ClickHouse, Redshift, BigQuery).

Реляционная база данных хранит информацию в связанных таблицах. Например, интернет-магазин может состоять из четырёх таблиц: customers (покупатели), orders (заказы), order_items (состав заказов) и products (товары). Таблицы связаны через первичные и внешние ключи (primary key / foreign key). Запрос к базе данных позволяет извлечь нужные данные из любой комбинации таких таблиц — одной командой.

Все команды языка структурированных запросов делятся на четыре подмножества: DDL управляет структурой базы данных, DML работает с данными, DCL регулирует права доступа, TCL управляет транзакциями. Управление базами данных через SQL позволяет решать задачи разной природы: от создания схемы до аналитических выгрузок.

Зачем нужны SQL-запросы: роль в работе аналитика

SQL — способ задать базе данных структурированный вопрос и получить точный ответ. Аналитик не листает миллионы строк вручную: он пишет запрос и получает готовую выгрузку.

Три основных сценария применения:

  • Формирование выгрузок — получить список клиентов с покупками за квартал.
  • Построение витрин данных — агрегировать показатели для дашборда или отчёта.
  • Администрирование баз данных — создавать таблицы, управлять индексами, настраивать права.

Запросы к базе данных используются и в продуктовой аналитике, и в финансовом планировании, и в маркетинге. По данным hh.ru, знание SQL — один из топ-3 обязательных навыков для бизнес-аналитика наряду с Excel и визуализацией данных.

Структура SQL-запроса: порядок выполнения команд

Полный шаблон SQL-запроса при написании выглядит так:

SELECT столбцы

FROM таблица

JOIN другая_таблица ON условие

WHERE условие_фильтрации

GROUP BY столбцы_группировки

HAVING условие_для_групп

ORDER BY столбец ASC|DESC

LIMIT N;

Обязательны только SELECT и FROM — остальные блоки подключаются по необходимости. Минимальный рабочий запрос выглядит так:

SELECT * FROM customers;

Ключевая точка путаницы для новичков: порядок написания не совпадает с порядком выполнения. СУБД обрабатывает запрос в следующей последовательности:

  1. FROM / JOIN — определяет набор таблиц и соединяет их.
  2. WHERE — фильтрует строки до группировки.
  3. GROUP BY — группирует оставшиеся строки.
  4. HAVING — фильтрует сгруппированные данные.
  5. SELECT — формирует набор столбцов.
  6. ORDER BY — сортирует результат.
  7. LIMIT — обрезает вывод до нужного числа строк.

Этот порядок объясняет большинство типичных ошибок начинающих — например, почему агрегатную функцию нельзя написать в WHERE, а псевдоним из SELECT недоступен в WHERE и GROUP BY.

Виды SQL-запросов: DDL, DML, DCL и TCL

Все команды языка структурированных запросов делятся на четыре функциональных подмножества — в зависимости от того, с чем именно работает команда.

Подмножество
Расшифровка
Основные команды
Назначение
DDL Data Definition Language CREATE, ALTER, DROP, TRUNCATE Управление структурой базы данных
DML Data Manipulation Language SELECT, INSERT, UPDATE, DELETE Работа с данными в таблицах
DCL Data Control Language GRANT, REVOKE Управление правами доступа
TCL Transaction Control Language COMMIT, ROLLBACK, SAVEPOINT Управление транзакциями

Помимо деления на подмножества, запросы разделяют по сложности: простые (одна таблица, без агрегаций), средние (GROUP BY + JOIN) и сложные (CTE, подзапросы, оконные функции). Простые запросы выполняются быстрее; сложные охватывают несколько таблиц и вычислительных шагов.

DDL-запросы — управление структурой базы данных

DDL (Data Definition Language) — подмножество SQL для определения структуры базы данных. Основные команды:

  • CREATE TABLE — создать таблицу со столбцами и типами данных.
  • ALTER TABLE — добавить или изменить столбец в существующей таблице.
  • DROP TABLE — удалить таблицу полностью вместе со всеми данными.
  • TRUNCATE — очистить содержимое таблицы, сохранив её структуру.

CREATE TABLE customers (

customer_id SERIAL PRIMARY KEY,

name VARCHAR(100),

city VARCHAR(50),

created_at DATE

);

Важная особенность DDL: изменения фиксируются автоматически (auto-commit). Откатить CREATE TABLE или DROP TABLE через ROLLBACK невозможно — в этом принципиальное отличие DDL от DML.

DML-запросы — операции с данными в таблицах

DML (Data Manipulation Language) работает с содержимым таблиц, не затрагивая их структуру. Четыре основные команды:

  • SELECT — выбрать данные; самая частая команда в аналитике.
  • INSERT INTO … VALUES … — добавить строки в таблицу.
  • UPDATE … SET … WHERE … — изменить значения в существующих строках.
  • DELETE FROM … WHERE … — удалить строки по условию.

INSERT INTO customers (name, city) VALUES (‘Анна’, ‘Москва’);

UPDATE customers SET city = ‘Санкт-Петербург’ WHERE customer_id = 1;

DELETE FROM customers WHERE customer_id = 1;

Изменения DML можно обернуть в транзакцию: если что-то пошло не так, команда ROLLBACK вернёт базу в исходное состояние. Структуру таблиц DML не изменяет — это зона ответственности DDL.

Простые SQL-запросы: SELECT, WHERE, ORDER BY с примерами

Простые sql запросы примеры строятся на трёх блоках: SELECT, FROM и необязательных WHERE и ORDER BY. Они работают с одной таблицей и не используют агрегаций или объединений — именно с них начинают изучение выборки данных.

SELECT определяет, какие столбцы попадут в результат. Символ * означает «все столбцы»; перечисление через запятую ограничивает выдачу нужными полями. Через AS задаётся псевдоним — удобно для вычисляемых полей и читаемости результата:

— Все столбцы таблицы

SELECT * FROM products;

— Конкретные столбцы + вычисляемое поле

SELECT

product_name,

price,

quantity,

price * quantity AS total_value

FROM order_items;

Псевдонимы улучшают читаемость и позволяют ссылаться на вычисляемый столбец в ORDER BY.

WHERE — фильтрация строк в SQL

WHERE фильтрует строки до GROUP BY — это второй шаг в порядке выполнения запроса. Поддерживаемые операторы сравнения и поиска:

  • =, !=, >, <, >=, <= — стандартное сравнение;
  • BETWEEN value1 AND value2 — фильтрация по диапазону;
  • IN (…) / NOT IN (…) — совпадение со списком значений;
  • LIKE ‘%шаблон%’ — поиск по маске (% — любое количество символов);
  • IS NULL / IS NOT NULL — проверка на отсутствие значения.

— Простая фильтрация данных

SELECT * FROM customers WHERE city = ‘Москва’;

— Список значений

SELECT * FROM products WHERE category IN (‘Электроника’, ‘Аксессуары’);

— Поиск по шаблону

SELECT * FROM customers WHERE name LIKE ‘Ан%’;

Условия комбинируются через AND, OR, NOT. Важно помнить: агрегатные функции (COUNT, SUM) в WHERE не работают — для фильтрации групп есть HAVING.

ORDER BY — сортировка результатов SQL

ORDER BY сортирует финальный результат запроса. По умолчанию применяется ASC — возрастание: числа от меньшего к большему, строки по алфавиту. DESC задаёт сортировку по убыванию.

— По убыванию цены

SELECT product_name, price

FROM products

ORDER BY price DESC;

— По двум столбцам: страна по алфавиту, внутри — город в обратном порядке

SELECT customer_id, country, city

FROM customers

ORDER BY country ASC, city DESC;

Сочетание ORDER BY DESC + LIMIT образует паттерн TOP-N — пять самых дорогих товаров, три последних заказа. В PostgreSQL дополнительно поддерживаются NULLS FIRST и NULLS LAST для управления позицией пустых значений в отсортированном списке.

SQL-запросы средней сложности: GROUP BY, HAVING, JOIN

Запросы среднего уровня агрегируют данные и объединяют несколько таблиц. Здесь открываются возможности для построения отчётов: продажи по городам, средний чек по категориям, история заказов клиента с детализацией позиций.

Логика прогрессии: простые запросы (одна таблица, фильтрация) → средние (GROUP BY + агрегатные функции, JOIN между таблицами) → сложные (подзапросы, CTE, оконные функции). Каждый уровень надстраивается над предыдущим, добавляя новые инструменты группировки данных и объединения таблиц.

GROUP BY и агрегатные функции SQL

GROUP BY группирует строки с одинаковыми значениями указанного столбца. Внутри каждой группы агрегатные функции вычисляют одно итоговое значение:

  • COUNT() — количество строк в группе;
  • SUM() — сумма значений;
  • AVG() — среднее значение;
  • MAX() / MIN() — максимум и минимум.

Правило SELECT: в список столбцов можно включать только те столбцы, которые указаны в GROUP BY, или агрегатные функции — ничего другого.

SELECT

city,

COUNT(*) AS order_count,

SUM(total_amount) AS revenue

FROM orders

GROUP BY city

ORDER BY revenue DESC;

Этот запрос вернёт список городов с количеством заказов и суммарной выручкой, отсортированный по убыванию. Именно через такие sql запросы примеры строятся базовые аналитические отчёты.

HAVING — фильтрация сгруппированных данных

HAVING — «WHERE для групп». Он фильтрует уже сгруппированные данные после GROUP BY, и именно здесь допустимы агрегатные функции.

Параметр
WHERE
HAVING
Когда фильтрует До GROUP BY После GROUP BY
Что фильтрует Отдельные строки Группы строк
Агрегатные функции ❌ нельзя ✅ можно
Аналогия Фильтр сырых данных Фильтр итогов

Типичная ошибка: WHERE COUNT(*) > 5 — SQL вернёт ошибку, потому что WHERE выполняется до GROUP BY и групп ещё не существует. Правильный вариант:

SELECT city, COUNT(*) AS cnt

FROM orders

WHERE order_date >= ‘2024-01-01’

GROUP BY city

Хотите сменить профессию или повысить квалификацию?

Федеральный проект «Активные меры содействия занятости» даёт возможность пройти обучение бесплатно за счёт государства

  • Программы от ведущих вузов России — от 2 месяцев
  • Удостоверение или диплом установленного образца
  • Центр карьеры: 7 500+ вакансий, помощь с трудоустройством
Оставить заявку
image

HAVING COUNT(*) > 5

ORDER BY cnt DESC;

В одном запросе могут присутствовать и WHERE, и HAVING: первый фильтрует строки до группировки, второй — группы после.

JOIN — объединение нескольких таблиц в SQL

JOIN объединяет таблицы по ключу, заданному в условии ON. Блок JOIN идёт после FROM, до WHERE.

Тип JOIN
Описание
Применение
INNER JOIN Только строки с совпадениями в обеих таблицах Заказы с известным клиентом
LEFT JOIN Все строки левой таблицы + совпадения из правой (NULL при отсутствии) Клиенты, в том числе без заказов
RIGHT JOIN Все строки правой таблицы + совпадения из левой Аналог LEFT JOIN с обратным порядком
FULL OUTER JOIN Все строки из обеих таблиц независимо от совпадений Полный реестр без потерь
CROSS JOIN Декартово произведение: каждая строка × каждую Генерация комбинаций

Паттерн «поиск сирот» — LEFT JOIN с условием WHERE правая_таблица.id IS NULL — находит строки левой таблицы без пары в правой:

— Товары без единого заказа

SELECT p.product_name

FROM products p

LEFT JOIN order_items oi ON p.product_id = oi.product_id

WHERE oi.product_id IS NULL;

Множественный JOIN последовательно объединяет более двух таблиц:

SELECT o.order_id, c.name, p.product_name, oi.quantity

FROM orders o

INNER JOIN customers c ON o.customer_id = c.customer_id

INNER JOIN order_items oi ON o.order_id = oi.order_id

INNER JOIN products p ON oi.product_id = p.product_id;

Сложные SQL-запросы с объяснением кода

Продвинутый уровень sql запросов примеры строится на трёх конструкциях: подзапросы, обобщённые табличные выражения (CTE) и оконные функции. Каждая решает свою задачу: подзапросы — вложенная логика фильтрации, CTE — читаемость и повторное использование, оконные функции — аналитика без сворачивания строк в группы.

Подзапросы (вложенные запросы SQL)

Вложенный запрос — SELECT внутри другого запроса. Размещается в трёх позициях:

  • WHERE — фильтрация по результату подзапроса;
  • FROM — подзапрос используется как временная таблица;
  • SELECT — вычисляемое поле для каждой строки.

— Товары с ценой выше средней по каталогу (подзапрос в WHERE)

SELECT product_name, price

FROM products

WHERE price > (SELECT AVG(price) FROM products);

Коррелированный подзапрос ссылается на столбцы внешнего запроса и выполняется для каждой строки — при больших таблицах это работает медленно. Его рекомендуют заменять на LEFT JOIN с GROUP BY: тот же результат, но СУБД обходит таблицу один раз вместо N раз.

CTE — временные именованные запросы в SQL

Обобщённые табличные выражения определяются через ключевое слово WITH и существуют только в рамках одного SQL-выражения:

WITH customer_segments AS (

SELECT

customer_id,

SUM(total_amount) AS total_spent,

CASE

WHEN SUM(total_amount) > 100000 THEN ‘VIP’

WHEN SUM(total_amount) > 30000 THEN ‘Gold’

ELSE ‘Regular’

END AS segment

FROM orders

GROUP BY customer_id

)

SELECT segment, COUNT(*) AS customers

FROM customer_segments

GROUP BY segment;

Несколько CTE перечисляются через запятую до финального SELECT. Преимущество перед вложенным запросом — читаемость: именованный блок вынесен вперёд, логика разбивается на шаги. Рекурсивный CTE (WITH RECURSIVE) обрабатывает иерархические структуры — например, дерево категорий товаров или цепочку подчинённости сотрудников.

Оконные функции SQL

Оконные функции вычисляют результат по набору строк, не сворачивая их — в этом ключевое отличие от GROUP BY. GROUP BY на выходе даёт одну строку на группу; оконная функция добавляет вычисленное значение рядом с каждой строкой исходной таблицы.

Синтаксис: функция() OVER (PARTITION BY … ORDER BY …)

Функция
Описание
Применение
ROW_NUMBER() Уникальный порядковый номер строки внутри раздела Нумерация заказов клиента
RANK() Ранг с пропусками при совпадении значений Рейтинг по продажам
DENSE_RANK() Ранг без пропусков при совпадении Плотный рейтинг
LAG() Значение предыдущей строки по заданному порядку Сравнение с прошлым периодом
LEAD() Значение следующей строки Прогноз следующего периода
SUM() OVER Накопительная (кумулятивная) сумма Нарастающий итог выручки

Три практических примера:

— ROW_NUMBER: нумерация заказов внутри каждого клиента

SELECT

order_id,

customer_id,

order_date,

ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) AS order_num

FROM orders;

— LAG: сравнение текущей суммы с предыдущим месяцем

SELECT

month,

revenue,

LAG(revenue) OVER (ORDER BY month) AS prev_revenue

FROM monthly_revenue;

— SUM OVER: накопительная сумма

SELECT

order_date,

total_amount,

SUM(total_amount) OVER (ORDER BY order_date) AS running_total

FROM orders;

Ключевая формулировка: «Как GROUP BY, но каждая строка остаётся в результате». Оконные функции незаменимы для рейтингов, динамики периодов и накопительных показателей.

Типовые SQL-паттерны для аналитиков

Прогрессия изучения SQL-запросов от новичка до продвинутого уровня

Три паттерна, которые решают большинство аналитических задач:

Паттерн 1 — Топ-N по группе. ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) нумерует строки внутри каждой категории. Внешний запрос фильтрует WHERE rn <= 3 — и возвращает три самых дорогих товара в каждой категории без дополнительных объединений.

Паттерн 2 — Динамика период к периоду. DATE_TRUNC(‘month’, order_date) группирует данные по месяцам, LAG() достаёт выручку предыдущего месяца — получается сравнение месяц к месяцу без дополнительных таблиц и самообъединений.

Паттерн 3 — Поиск «сирот». LEFT JOIN + WHERE правая_таблица.id IS NULL — классический способ найти строки без пары: товары без ни одного заказа, клиенты без транзакций, категории без товаров.

Все три паттерна складываются из блоков, разобранных выше. Понимание того, как работают sql запросы примеры каждого уровня, позволяет комбинировать их под любую задачу — от простой выгрузки до многоуровневого аналитического отчёта.

Типичные ошибки при написании SQL-запросов

Большинство ошибок новичков вытекают из непонимания порядка выполнения запроса — в частности, из того, что SELECT выполняется позже FROM и WHERE.

Ошибка
Неправильно
Правильно
Агрегатная функция в WHERE WHERE COUNT(*) > 5 HAVING COUNT(*) > 5
Сравнение с NULL через = WHERE city = NULL WHERE city IS NULL
Деление на ноль revenue / users revenue / NULLIF(users, 0)
GROUP BY без агрегатной функции в SELECT SELECT city, name … GROUP BY city SELECT city, COUNT(*) … GROUP BY city
HAVING вместо WHERE для неагрегированного условия GROUP BY city HAVING city = ‘Москва’ WHERE city = ‘Москва’ GROUP BY city

Разберём три ключевых случая. Агрегатная функция в WHERE — результат непонимания того, что WHERE выполняется до GROUP BY: в этот момент групп ещё нет. Сравнение city = NULL всегда возвращает UNKNOWN, а не TRUE — для проверки на пустое значение SQL использует специальный оператор IS NULL / IS NOT NULL. Деление на ноль возникает в расчётах конверсий и средних: NULLIF(users, 0) вернёт NULL при нулевом знаменателе, и деление безопасно завершится NULL вместо ошибки. COALESCE(expression, 0) дополнительно заменяет NULL на ноль там, где нужен чистый числовой результат.

SQL — фундамент работы с данными, и освоить его реально за 2–3 месяца. В рамках федерального проекта «Активные меры содействия занятости» нацпроекта «Кадры» можно пройти обучение по программе «Специалист по аналитике и базам данных в информационных системах» с нуля, без отрыва от работы и за счёт государства. Смотрите каталог доступных программ — там же условия участия и запись.

Часто задаваемые вопросы

В чём разница между WHERE и HAVING в SQL?

WHERE фильтрует строки до GROUP BY — агрегатные функции (COUNT, SUM) в нём использовать нельзя. HAVING фильтрует уже сгруппированные данные после GROUP BY — именно здесь применяются условия COUNT(*) > 5 и аналогичные. Типичная ошибка: написать WHERE COUNT(*) > 5 — SQL вернёт ошибку. Правильно: GROUP BY city HAVING COUNT(*) > 5.

Что такое подзапрос и когда его применять?

Подзапрос — SELECT внутри другого запроса. Используется в WHERE (отбор по условию: цена выше средней), FROM (временная таблица) и SELECT (вычисляемое поле для каждой строки). Коррелированный подзапрос выполняется для каждой строки внешнего запроса — при больших таблицах медленнее. Его часто заменяют на JOIN с GROUP BY для повышения производительности.

Чем CTE отличается от подзапроса?

CTE (WITH … AS) именован и вынесен до основного запроса — читается как пошаговый алгоритм. Подзапрос встроен в тело и затрудняет чтение при нескольких уровнях вложенности. CTE можно переиспользовать несколько раз в одном выражении. Рекурсивный CTE (WITH RECURSIVE) обрабатывает иерархические данные — то, что подзапрос сделать не может.

Зачем нужны оконные функции, если есть GROUP BY?

GROUP BY сворачивает строки: на выходе одна строка на группу. Оконные функции оставляют все исходные строки и добавляют рядом агрегированный результат. ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) пронумерует заказы каждого клиента — GROUP BY на это не способен. Оконные функции незаменимы для рейтингов, накопительных сумм и сравнения с предыдущим периодом.

Какие типы JOIN существуют в SQL?

INNER JOIN — только совпадающие строки из обеих таблиц. LEFT JOIN — все строки левой таблицы плюс совпадения из правой (NULL если нет пары). RIGHT JOIN — зеркало LEFT JOIN. FULL OUTER JOIN — все строки из обеих таблиц независимо от совпадений. CROSS JOIN — декартово произведение всех комбинаций. В аналитике чаще всего используются INNER JOIN и LEFT JOIN.

Как найти записи без пары в другой таблице?

Паттерн «поиск сирот»: LEFT JOIN + WHERE правая_таблица.id IS NULL. Пример — товары без единого заказа: SELECT p.product_name FROM products p LEFT JOIN order_items oi ON p.product_id = oi.product_id WHERE oi.product_id IS NULL. LEFT JOIN возвращает все товары; там, где заказов нет, order_items.product_id равен NULL — это и есть условие фильтрации.

В чём разница между DDL и DML-запросами?

DDL (CREATE, ALTER, DROP) управляет структурой таблиц: создаёт, изменяет, удаляет схему. Изменения DDL фиксируются автоматически (auto-commit) — откатить через ROLLBACK нельзя. DML (SELECT, INSERT, UPDATE, DELETE) работает с данными в уже существующих таблицах и не меняет их структуру. Изменения DML можно обернуть в транзакцию и при необходимости откатить.

Как работает GROUP BY с несколькими столбцами?

GROUP BY country, city группирует строки по каждой уникальной комбинации значений — отдельно «Германия, Берлин», «Германия, Мюнхен» и т.д. В SELECT обязательно перечислить те же столбцы плюс агрегатные функции: SELECT country, city, COUNT(*) FROM customers GROUP BY country, city. Порядок столбцов в GROUP BY влияет только на читаемость, не на результат.

Что делает ORDER BY DESC в SQL?

ORDER BY сортирует финальный результат запроса. ASC — возрастание (по умолчанию): числа от меньшего, строки по алфавиту. DESC — убывание. Можно комбинировать: ORDER BY category ASC, price DESC — сортировка сначала по категории, внутри категории по цене от дорогого. Вместе с LIMIT реализует паттерн TOP-N: ORDER BY price DESC LIMIT 5 — пять самых дорогих товаров.

Как начать изучать SQL с нуля?

Начните с SELECT + WHERE + ORDER BY — они покрывают 80% задач начинающего аналитика. Затем добавьте GROUP BY с агрегатными функциями и JOIN для работы с несколькими таблицами. После этого переходите к подзапросам и CTE, финально — к оконным функциям. Программа «Специалист по аналитике и базам данных в информационных системах» охватывает весь этот путь с практикой на реальных наборах данных.

Подайте заявку —
забронируйте место в группе

45 000 мест на 2026 год. Бесплатное обучение по федеральному проекту «Активные меры содействия занятости»

  • Онлайн
  • От 2 месяцев
  • Бесплатно
  • Диплом
Учиться бесплатно
icon