Что такое SQL и зачем он нужен в 2026 году
SQL (Structured Query Language) — это язык структурированных запросов, который позволяет общаться с базами данных. С его помощью вы можете извлекать информацию, изменять её, анализировать и управлять данными в реляционных СУБД. SQL был создан в 1970-х годах, но остаётся актуальным и в 2026 году.
Любая современная компания работает с данными: о клиентах, продажах, товарах, транзакциях. Эти данные хранятся в базах, а SQL — инструмент для работы с ними. Без SQL невозможно получить ответы на бизнес-вопросы: сколько пользователей зарегистрировалось за месяц, какой товар приносит максимальную прибыль, какие клиенты совершили повторную покупку.
В 2026 году SQL — это универсальный навык для специалистов из разных сфер:
- Аналитики данных используют SQL для сегментации клиентов, расчёта метрик, построения витрин данных
- Продуктовые менеджеры применяют запросы для анализа поведения пользователей и A/B-тестирования
- Маркетологи выгружают данные для оценки эффективности кампаний
- Разработчики проектируют базы данных и оптимизируют запросы
- Владельцы бизнеса получают актуальную отчётность без помощи техспециалистов
SQL не требует глубоких знаний программирования. Синтаксис читается почти как естественный язык: SELECT (выбрать), WHERE (где), FROM (из). Это делает его доступным для начинающих, которые могут освоить базовые запросы за несколько недель.
Статистика и карьерные перспективы
SQL в 2026 году — универсальный инструмент для работы с данными, который требуется в большинстве вакансий, связанных с анализом и работой с информацией. Аналитики данных востребованы во всех сферах, и медианный ежемесячный доход аналитиков данных — 130 000 рублей.
Рассмотрим конкретные цифры по зарплатам специалистов со знанием SQL в России в 2026 году:
- Junior-аналитик данных: от 60 000 до 80 000 рублей в месяц
- Middle-аналитик данных: от 139 000 до 180 000 рублей в месяц
- Senior-аналитик данных: от 250 000 до 350 000 рублей в месяц
Аналитик по данным зарабатывает 163 500 рублей в среднем по России, согласно данным Хабр Карьеры. Зарплаты аналитиков в России выросли на 7% в первой половине 2024 года, и в среднем доход специалиста составляет 160 000 рублей.
Для SQL-разработчиков цифры несколько выше. Средняя зарплата по должности разработчик SQL в России за 2026 год — 153 000 рублей, чаще всего зарплаты находятся в диапазоне от 113 000 до 192 000 рублей.
По специализациям картина выглядит следующим образом:
- Бизнес-аналитик: средняя зарплата 168 000 рублей (Junior от 60 000, Middle от 139 000, Senior от 250 000 рублей)
- Системный аналитик: медианная зарплата 203 000–225 000 рублей (Junior от 80 000, Middle от 180 000, Senior до 350 000 рублей)
- Data Scientist: в среднем 211 666 рублей в месяц
Переход Junior → Middle занимает 1–2 года опыта в data analysis and reporting. Это означает, что при систематическом обучении и практике вы можете выйти на доход от 140 000 рублей уже через год-полтора работы.
Основы баз данных: реляционные БД, таблицы, строки, столбцы
База данных (БД) — это организованное хранилище информации, которое позволяет быстро находить, добавлять, изменять и удалять данные. Реляционные базы данных — самый распространённый тип БД, где информация структурирована в виде таблиц.
Таблица — это основная структура данных, похожая на электронную таблицу Excel. Каждая таблица имеет название и содержит данные об определённой сущности: клиенты, заказы, товары, транзакции.
Таблица состоит из:
- Столбцов (полей) — вертикальных элементов, которые определяют тип данных. Например, в таблице «Клиенты» могут быть столбцы: id, имя, email, дата_регистрации
- Строк (записей) — горизонтальных элементов, каждая строка представляет отдельный объект. Например, одна строка = один клиент
Рассмотрим пример таблицы Пользователи:
| id | имя | город | дата_регистрации | |
|---|---|---|---|---|
| 1 | Анна | anna@mail.ru | Москва | 2026-01-15 |
| 2 | Сергей | sergey@gmail.com | Санкт-Петербург | 2026-02-10 |
| 3 | Мария | maria@yandex.ru | Казань | 2026-03-01 |
В реляционных БД таблицы связаны между собой через ключи:
- Первичный ключ (PRIMARY KEY) — уникальный идентификатор каждой строки, обычно это поле id
- Внешний ключ (FOREIGN KEY) — поле, которое ссылается на первичный ключ другой таблицы и создаёт связь между ними
Например, таблица «Заказы» может содержать поле user_id, которое ссылается на id в таблице «Пользователи». Это позволяет узнать, какой пользователь сделал конкретный заказ.
СУБД (Система Управления Базами Данных) — это программное обеспечение для работы с БД. Именно СУБД обрабатывает ваши SQL-запросы и выполняет операции с данными: PostgreSQL, MySQL, MS SQL Server, Oracle — всё это разные СУБД.
Принципы работы с реляционными БД:
- Данные не дублируются — каждая информация хранится в одном месте
- Связи между таблицами позволяют объединять данные из разных источников
- Целостность данных обеспечивается через ограничения и ключи
- SQL позволяет получать нужные данные одним запросом, даже если они распределены по нескольким таблицам
Выбор СУБД: PostgreSQL vs MySQL vs MS SQL vs Oracle
Выбор СУБД зависит от задач, размера проекта и инфраструктуры компании. В 2026 году наиболее популярны четыре системы, каждая со своими сильными сторонами.
PostgreSQL — объектно-реляционная СУБД с открытым исходным кодом. PostgreSQL ranked as the most widely used database among professional developers, overtaking MySQL for the first time, и 65% разработчиков указали предпочтение PostgreSQL для новых проектов.
Преимущества PostgreSQL:
- Полностью бесплатная, лицензия MIT/BSD без ограничений
- Мощная поддержка JSON, массивов, диапазонов типов
- Продвинутые функции: оконные функции, CTE, full-text search
- Расширяемость через плагины (PostGIS для геоданных, pgvector для AI)
- Отличная производительность на сложных запросах с JOIN и подзапросами
- Активное сообщество и прозрачное развитие
Используется: в продуктовой аналитике, стартапах, SaaS-платформах, научных проектах. Популярен у разработчиков Python, JavaScript, Ruby.
MySQL — самая распространённая открытая СУБД, принадлежащая Oracle. MySQL — это самая распространённая Relational Database Management System в мире, и в 2026 году она имеет вторую по величине популярность среди разработчиков.
Преимущества MySQL:
- Простота установки и настройки
- Высокая скорость на простых запросах и операциях чтения
- Встроена в популярный стек LAMP (Linux, Apache, MySQL, PHP)
- Отличная документация и большое сообщество
- Стабильность при регулярном обслуживании БД
Используется: в WordPress, e-commerce (Shopify), веб-приложениях на PHP, системах с высокой нагрузкой на запись.
MS SQL Server — коммерческая СУБД от Microsoft для корпоративного сегмента.
Преимущества MS SQL Server:
- Глубокая интеграция с экосистемой Microsoft (.NET, Azure, Power BI)
- Мощные инструменты администрирования и мониторинга
- Встроенные средства аналитики и отчётности
- Профессиональная техподдержка от Microsoft
- Высокий уровень безопасности и соответствия стандартам
Используется: в крупных корпорациях, банках, госучреждениях, ERP-системах (1C, SAP).
Oracle Database — флагманская коммерческая СУБД для энтерпрайз-сегмента.
Преимущества Oracle:
- Максимальная производительность на огромных объёмах данных
- Продвинутые функции партиционирования и кластеризации
- Высокая надёжность и отказоустойчивость
- Комплексная техподдержка уровня enterprise
Используется: в банковском секторе, телекоммуникациях, крупных производственных компаниях.
| СУБД | Лицензия | Сложность | Лучше всего для |
|---|---|---|---|
| PostgreSQL | Бесплатно | Средняя | Аналитика, новые проекты, стартапы |
| MySQL | Бесплатно | Низкая | Веб-приложения, WordPress, PHP-проекты |
| MS SQL Server | Платно | Средняя | Корпоративная отчётность, Microsoft-среда |
| Oracle | Платно | Высокая | Банки, энтерпрайз, большие данные |
Инструменты для работы: DBeaver, PhpMyAdmin, облачные решения
Для написания SQL-запросов и работы с базами данных вам понадобится специальный инструмент — клиент СУБД или IDE (интегрированная среда разработки). В 2026 году есть как бесплатные универсальные решения, так и специализированные инструменты.
DBeaver — бесплатный кроссплатформенный инструмент для работы с любыми СУБД (PostgreSQL, MySQL, MS SQL, Oracle, SQLite и другие).
Преимущества DBeaver:
- Поддержка всех популярных баз данных в одном интерфейсе
- Визуальный редактор запросов с подсветкой синтаксиса
- Автодополнение названий таблиц и полей
- Просмотр структуры БД в виде дерева
- Экспорт результатов в CSV, Excel, JSON
- Бесплатная Community-версия для большинства задач
Идеально подходит для начинающих и аналитиков данных, которым нужно работать с несколькими типами баз одновременно.
PhpMyAdmin — веб-интерфейс для управления MySQL и MariaDB.
Преимущества PhpMyAdmin:
- Работает через браузер, не требует установки на компьютер
- Удобен для быстрых операций с БД на хостинге
- Визуальное создание и редактирование таблиц
- Интеграция с большинством веб-хостингов
Используется в основном веб-разработчиками для управления MySQL на серверах.
pgAdmin — официальный графический клиент для PostgreSQL.
Преимущества pgAdmin:
- Полная поддержка всех возможностей PostgreSQL
- Визуальный конструктор запросов
- Инструменты мониторинга производительности
- Управление пользователями и правами доступа
Облачные решения — платформы с готовыми базами данных и встроенными редакторами:
- Google BigQuery — аналитическая БД от Google для работы с большими данными, запросы пишутся на SQL-диалекте
- AWS RDS — управляемые базы данных PostgreSQL, MySQL, MS SQL в облаке Amazon
- Supabase — open-source платформа на базе PostgreSQL с веб-интерфейсом и API
- PlanetScale — serverless MySQL с Git-подобным управлением версиями
Metabase — open-source BI-инструмент с SQL-редактором и визуализацией данных.
Преимущества Metabase:
- Позволяет писать SQL-запросы и сразу строить графики
- Создание дашбордов без программирования
- Подключение к PostgreSQL, MySQL, BigQuery, ClickHouse
- Удобен для аналитиков, которым нужна визуализация
Для начинающих оптимальный выбор — DBeaver для локальной работы или встроенные редакторы на платформах для практики (Stepik, SQL Academy). Эти инструменты бесплатны и не требуют сложной настройки.
ТОП-10 SQL запросов для начинающих с примерами кода
Освоение SQL начинается с базовых конструкций, которые покрывают 80% повседневных задач аналитика. Ниже — десять ключевых типов запросов с практическими примерами на основе таблицы Заказы.
Структура таблицы для примеров:
| id | user_id | товар | цена | количество | дата_заказа |
|---|---|---|---|---|---|
| 1 | 101 | Ноутбук | 65000 | 1 | 2026-03-01 |
| 2 | 102 | Мышь | 1500 | 2 | 2026-03-05 |
| 3 | 101 | Клавиатура | 3500 | 1 | 2026-03-10 |
1. SELECT — выборка всех данных
SELECT * FROM заказы;
Возвращает все строки и столбцы из таблицы.
2. SELECT с указанием столбцов
SELECT товар, цена, дата_заказа FROM заказы;
Выбирает только нужные поля, игнорируя остальные.
3. WHERE — фильтрация по условию
SELECT * FROM заказы WHERE цена > 5000;
Показывает только заказы дороже 5 000 рублей.
4. ORDER BY — сортировка результатов
SELECT * FROM заказы ORDER BY цена DESC;
Сортирует заказы по убыванию цены (самые дорогие сверху).
5. LIMIT — ограничение количества строк
SELECT * FROM заказы ORDER BY дата_заказа DESC LIMIT 5;
Возвращает пять последних заказов.
6. COUNT — подсчёт количества записей
SELECT COUNT(*) FROM заказы WHERE дата_заказа >= '2026-03-01';
Считает, сколько заказов было сделано с 1 марта.
7. SUM — суммирование значений
SELECT SUM(цена * количество) AS общая_выручка FROM заказы;
Рассчитывает общую выручку по всем заказам.
8. GROUP BY — группировка данных
SELECT user_id, COUNT(*) AS количество_заказов FROM заказы GROUP BY user_id;
Показывает, сколько заказов сделал каждый пользователь.
9. HAVING — фильтрация после группировки
SELECT user_id, SUM(цена * количество) AS сумма_покупок FROM заказы GROUP BY user_id HAVING сумма_покупок > 10000;
Находит пользователей, которые потратили более 10 000 рублей.
10. DISTINCT — уникальные значения
SELECT DISTINCT товар FROM заказы;
Возвращает список уникальных товаров без дубликатов.
Эти десять конструкций — фундамент SQL. Комбинируя их, вы сможете решать большинство аналитических задач: формировать отчёты, считать метрики, сегментировать пользователей, находить аномалии в данных.
SELECT: выборка данных из таблиц
SELECT — самая частая команда в SQL, с которой начинается любой запрос на извлечение данных. Синтаксис читается интуитивно: «выбери (SELECT) определённые поля из (FROM) конкретной таблицы».
Базовый синтаксис:
SELECT столбец1, столбец2, столбец3 FROM название_таблицы;
Пример: выбрать имена и email из таблицы пользователи:
SELECT имя, email FROM пользователи;
Выборка всех столбцов:
SELECT * FROM пользователи;
Символ * означает «все столбцы». Это удобно для быстрого просмотра данных, но в продакшене лучше указывать конкретные поля — так запрос работает быстрее.
Переименование столбцов с помощью AS:
SELECT имя AS "Имя пользователя", email AS "Электронная почта", дата_регистрации AS "Дата регистрации" FROM пользователи;
Алиасы (псевдонимы) делают результаты понятнее, особенно при построении отчётов.
Вычисления в SELECT:
SELECT товар, цена, количество, цена * количество AS итоговая_стоимость FROM заказы;
SQL позволяет выполнять математические операции прямо в запросе: сложение, вычитание, умножение, деление.
Константы и строковые литералы:
SELECT 'Пользователь' AS тип, имя, город FROM пользователи;
Можно добавлять фиксированные значения в результат — это полезно при объединении данных из нескольких таблиц.
Функции в SELECT:
SELECT UPPER(имя) AS имя_заглавными, LENGTH(email) AS длина_email, CURRENT_DATE AS сегодня FROM пользователи;
SQL содержит десятки встроенных функций для работы со строками, датами, числами. UPPER переводит текст в верхний регистр, LENGTH возвращает длину строки, CURRENT_DATE — текущую дату.
SELECT — это точка входа в работу с данными. Освоив её вариации, вы сможете формировать отчёты любой сложности.
WHERE: фильтрация данных
WHERE добавляет условия к запросу, позволяя отобрать только нужные строки. Без WHERE вы получаете все записи из таблицы, с WHERE — только те, что соответствуют критериям.
Базовый синтаксис:
SELECT столбцы FROM таблица WHERE условие;
Операторы сравнения:
-- Точное совпадение SELECT * FROM заказы WHERE город = 'Москва'; -- Больше, меньше SELECT * FROM заказы WHERE цена > 10000; SELECT * FROM заказы WHERE количество <= 5; -- Не равно SELECT * FROM пользователи WHERE статус != 'активный';
Логические операторы AND, OR, NOT:
-- AND: оба условия должны быть истинны SELECT * FROM заказы WHERE город = 'Москва' AND цена > 5000; -- OR: хотя бы одно условие истинно SELECT * FROM заказы WHERE город = 'Москва' OR город = 'Санкт-Петербург'; -- NOT: инверсия условия SELECT * FROM пользователи WHERE NOT город = 'Москва';
BETWEEN — диапазон значений:
SELECT * FROM заказы WHERE цена BETWEEN 5000 AND 15000;
Эквивалентно цена >= 5000 AND цена <= 15000.
IN — проверка вхождения в список:
SELECT * FROM заказы
WHERE город IN ('Москва', 'Санкт-Петербург', 'Казань');
Вместо трёх OR один компактный IN.
LIKE — поиск по шаблону:
-- Все email, заканчивающиеся на @gmail.com SELECT * FROM пользователи WHERE email LIKE '%@gmail.com'; -- Имена, начинающиеся на "А" SELECT * FROM пользователи WHERE имя LIKE 'А%'; -- Телефоны с кодом 495 (Москва) SELECT * FROM пользователи WHERE телефон LIKE '+7495%';
Символ % означает «любые символы в любом количестве», _ — «один любой символ».
IS NULL / IS NOT NULL — проверка на пустые значения:
-- Пользователи без email SELECT * FROM пользователи WHERE email IS NULL; -- Пользователи с указанным email SELECT * FROM пользователи WHERE email IS NOT NULL;
Работа с датами:
-- Заказы за март 2026 SELECT * FROM заказы WHERE дата_заказа >= '2026-03-01' AND дата_заказа < '2026-04-01'; -- Заказы за последние 7 дней SELECT * FROM заказы WHERE дата_заказа >= CURRENT_DATE - INTERVAL '7 days';
JOIN: объединение таблиц
JOIN — ключевая конструкция реляционных БД, которая позволяет объединять данные из нескольких таблиц по общему полю. Без JOIN вы работаете только с одной таблицей, с JOIN — строите сложные аналитические запросы.
Рассмотрим две таблицы:
Таблица пользователи:
| user_id | имя | город |
|---|---|---|
| 1 | Анна | Москва |
| 2 | Сергей | Казань |
Таблица заказы:
| order_id | user_id | товар | цена |
|---|---|---|---|
| 101 | 1 | Ноутбук | 65000 |
| 102 | 1 | Мышь | 1500 |
| 103 | 2 | Клавиатура | 3500 |
INNER JOIN — пересечение таблиц:
SELECT пользователи.имя, заказы.товар, заказы.цена FROM пользователи INNER JOIN заказы ON пользователи.user_id = заказы.user_id;
Результат содержит только те строки, где есть совпадение по user_id в обеих таблицах. Если у пользователя нет заказов, он не попадёт в выборку.
LEFT JOIN — все строки из левой таблицы:
SELECT пользователи.имя, заказы.товар, заказы.цена FROM пользователи LEFT JOIN заказы ON пользователи.user_id = заказы.user_id;
Возвращает всех пользователей. Если у пользователя нет заказов, поля из таблицы заказы будут NULL. Это полезно для анализа: «сколько пользователей ничего не купили».
RIGHT JOIN — все строки из правой таблицы:
SELECT пользователи.имя, заказы.товар FROM пользователи RIGHT JOIN заказы ON пользователи.user_id = заказы.user_id;
Обратная логика LEFT JOIN — все заказы, даже если нет информации о пользователе. Используется редко.
FULL OUTER JOIN — все строки из обеих таблиц:
SELECT пользователи.имя, заказы.товар FROM пользователи FULL OUTER JOIN заказы ON пользователи.user_id = заказы.user_id;
Объединяет результаты LEFT и RIGHT JOIN. Поддерживается в PostgreSQL, но отсутствует в MySQL (там используют UNION).
Множественные JOIN:
SELECT пользователи.имя, заказы.товар, категории.название FROM пользователи INNER JOIN заказы ON пользователи.user_id = заказы.user_id INNER JOIN категории ON заказы.category_id = категории.id;
Можно объединять три, четыре и более таблиц последовательно.
Алиасы для таблиц:
SELECT u.имя, o.товар, o.цена FROM пользователи AS u INNER JOIN заказы AS o ON u.user_id = o.user_id;
Короткие алиасы (u, o) упрощают запись длинных запросов.
GROUP BY и агрегатные функции
GROUP BY группирует строки с одинаковыми значениями в указанном поле, а агрегатные функции вычисляют итоги по каждой группе: COUNT (количество), SUM (сумма), AVG (среднее), MIN (минимум), MAX (максимум).
Подсчёт количества заказов по городам:
SELECT город, COUNT(*) AS количество_заказов FROM заказы GROUP BY город;
Результат покажет, сколько заказов пришло из каждого города.
Сумма выручки по пользователям:
SELECT user_id, SUM(цена * количество) AS общая_выручка FROM заказы GROUP BY user_id;
Средний чек по месяцам:
SELECT
DATE_TRUNC('month', дата_заказа) AS месяц,
AVG(цена) AS средний_чек
FROM заказы
GROUP BY месяц
ORDER BY месяц;
DATE_TRUNC округляет дату до начала месяца, позволяя группировать по периодам.
Минимальная и максимальная цена по категориям:
SELECT категория, MIN(цена) AS минимальная_цена, MAX(цена) AS максимальная_цена FROM товары GROUP BY категория;
Группировка по нескольким полям:
SELECT город, категория, COUNT(*) AS количество FROM заказы GROUP BY город, категория;
Это создаёт подгруппы: сначала группировка по городу, затем внутри каждого города — по категории.
HAVING — фильтрация после группировки:
SELECT user_id, COUNT(*) AS количество_заказов, SUM(цена) AS сумма_покупок FROM заказы GROUP BY user_id HAVING COUNT(*) > 3 AND SUM(цена) > 20000;
HAVING работает с результатами агрегации, WHERE — с исходными строками. Это частая ошибка новичков: пытаться использовать WHERE с COUNT или SUM.
Практический пример: анализ активности пользователей
SELECT user_id, COUNT(DISTINCT дата_заказа) AS дней_с_покупками, COUNT(*) AS всего_заказов, ROUND(AVG(цена), 2) AS средний_чек, SUM(цена) AS общая_сумма FROM заказы WHERE дата_заказа >= '2026-01-01' GROUP BY user_id HAVING COUNT(*) >= 2 ORDER BY общая_сумма DESC LIMIT 10;
Этот запрос находит топ-10 пользователей по выручке за 2026 год, которые сделали минимум 2 заказа.
ORDER BY: сортировка результатов
ORDER BY упорядочивает результаты запроса по одному или нескольким столбцам. По умолчанию сортировка идёт по возрастанию (ASC), для обратного порядка используется DESC.
Сортировка по одному полю:
-- По возрастанию цены SELECT * FROM товары ORDER BY цена; -- По убыванию цены (самые дорогие сначала) SELECT * FROM товары ORDER BY цена DESC;
Сортировка по нескольким полям:
SELECT * FROM заказы ORDER BY город, дата_заказа DESC;
Сначала сортировка по городу (алфавитный порядок), затем внутри каждого города — по дате от новых к старым.
Сортировка по вычисляемому полю:
SELECT товар, цена, количество, цена * количество AS итого FROM заказы ORDER BY итого DESC;
Сортировка по позиции столбца:
SELECT имя, email, город FROM пользователи ORDER BY 3;
Цифра 3 означает «сортировать по третьему столбцу в SELECT» (город). Допустимо, но менее читаемо, чем ORDER BY город.
Сортировка с NULL:
-- NULL в конце SELECT * FROM пользователи ORDER BY email NULLS LAST; -- NULL в начале SELECT * FROM пользователи ORDER BY email NULLS FIRST;
В PostgreSQL можно явно указать, куда помещать NULL-значения.
Комбинация с LIMIT для топов:
-- Топ-5 самых дорогих заказов SELECT * FROM заказы ORDER BY цена DESC LIMIT 5; -- Топ-10 активных пользователей SELECT user_id, COUNT(*) AS заказов FROM заказы GROUP BY user_id ORDER BY заказов DESC LIMIT 10;
ORDER BY всегда выполняется в конце запроса, после WHERE, GROUP BY и HAVING. Это важно для понимания последовательности обработки.
INSERT, UPDATE, DELETE: изменение данных
До сих пор мы только читали данные с помощью SELECT. Теперь рассмотрим операции изменения: добавление новых записей (INSERT), обновление существующих (UPDATE) и удаление (DELETE).
INSERT — добавление новых строк:
-- Добавить одного пользователя
INSERT INTO пользователи (имя, email, город)
VALUES ('Ирина', 'irina@mail.ru', 'Екатеринбург');
-- Добавить несколько пользователей за раз
INSERT INTO пользователи (имя, email, город)
VALUES
('Дмитрий', 'dmitry@gmail.com', 'Москва'),
('Ольга', 'olga@yandex.ru', 'Казань'),
('Павел', 'pavel@mail.ru', 'Новосибирск');
Если у таблицы есть поле с автоинкрементом (обычно id), его можно не указывать — СУБД присвоит значение автоматически.
INSERT с возвратом созданной записи (PostgreSQL):
INSERT INTO пользователи (имя, email)
VALUES ('Алексей', 'alexey@mail.ru')
RETURNING id, имя, created_at;
RETURNING позволяет сразу получить созданную запись с её id и другими полями.
UPDATE — обновление существующих записей:
-- Изменить email одного пользователя UPDATE пользователи SET email = 'new_email@gmail.com' WHERE user_id = 5; -- Обновить несколько полей UPDATE пользователи SET город = 'Санкт-Петербург', статус = 'активный', обновлено_в = CURRENT_TIMESTAMP WHERE user_id = 10;
UPDATE с условием на основе вычислений:
-- Применить скидку 10% ко всем товарам дороже 50 000 UPDATE товары SET цена = цена * 0.9 WHERE цена > 50000;
DELETE — удаление строк:
-- Удалить одного пользователя DELETE FROM пользователи WHERE user_id = 15; -- Удалить всех неактивных пользователей DELETE FROM пользователи WHERE статус = 'неактивный'; -- Удалить заказы старше года DELETE FROM заказы WHERE дата_заказа < CURRENT_DATE - INTERVAL '1 year';
TRUNCATE — быстрое удаление всех данных:
TRUNCATE TABLE пользователи;
Работает быстрее DELETE, но удаляет все строки без возможности отката (если нет транзакций).
Транзакции для безопасности:
BEGIN; UPDATE счета SET баланс = баланс - 1000 WHERE user_id = 1; UPDATE счета SET баланс = баланс + 1000 WHERE user_id = 2; COMMIT;
Транзакция гарантирует, что либо выполнятся обе операции, либо ни одна. Если что-то пошло не так, используйте ROLLBACK для отмены изменений.
Подзапросы (subqueries)
Подзапрос — это SELECT внутри другого SELECT. Он позволяет использовать результаты одного запроса в качестве данных для другого. Подзапросы делают код более читаемым и гибким.
Подзапрос в WHERE:
-- Найти пользователей, которые сделали заказ дороже среднего SELECT * FROM пользователи WHERE user_id IN ( SELECT user_id FROM заказы WHERE цена > (SELECT AVG(цена) FROM заказы) );
Внутренний подзапрос вычисляет среднюю цену, затем находит заказы выше средней, и в итоге возвращаются пользователи этих заказов.
Подзапрос в SELECT:
SELECT имя, (SELECT COUNT(*) FROM заказы WHERE заказы.user_id = пользователи.user_id) AS количество_заказов FROM пользователи;
Для каждого пользователя подзапрос считает количество его заказов. Это называется коррелированный подзапрос — он зависит от внешнего запроса.
Подзапрос в FROM (производная таблица):
SELECT
город,
AVG(сумма_заказов) AS средняя_сумма_на_пользователя
FROM (
SELECT
пользователи.город,
SUM(заказы.цена) AS сумма_заказов
FROM пользователи
JOIN заказы ON пользователи.user_id = заказы.user_id
GROUP BY пользователи.user_id, пользователи.город
) AS пользовательские_суммы
GROUP BY город;
Подзапрос сначала считает сумму заказов каждого пользователя, затем внешний запрос группирует по городам и вычисляет среднее.
EXISTS — проверка существования:
-- Пользователи, у которых есть хотя бы один заказ SELECT * FROM пользователи WHERE EXISTS ( SELECT 1 FROM заказы WHERE заказы.user_id = пользователи.user_id );
EXISTS возвращает TRUE, если подзапрос нашёл хотя бы одну строку. Часто работает быстрее, чем JOIN или IN.
NOT EXISTS — обратная логика:
-- Пользователи без заказов SELECT * FROM пользователи WHERE NOT EXISTS ( SELECT 1 FROM заказы WHERE заказы.user_id = пользователи.user_id );
Подзапросы с ANY / ALL:
-- Товары дороже любого товара из категории "Аксессуары" SELECT * FROM товары WHERE цена > ANY ( SELECT цена FROM товары WHERE категория = 'Аксессуары' ); -- Товары дороже всех товаров из категории "Аксессуары" SELECT * FROM товары WHERE цена > ALL ( SELECT цена FROM товары WHERE категория = 'Аксессуары' );
Подзапросы мощные, но могут снижать производительность на больших данных. Часто их можно заменить на JOIN или CTE (Common Table Expressions).
Оконные функции (window functions)
Оконные функции — продвинутый инструмент SQL, который позволяет выполнять вычисления по группам строк (окнам) без схлопывания результата, как в GROUP BY. Это ключевой навык для middle-аналитика.
Базовый синтаксис:
функция() OVER ( PARTITION BY поле_группировки ORDER BY поле_сортировки )
ROW_NUMBER — нумерация строк:
SELECT имя, город, зарплата, ROW_NUMBER() OVER (PARTITION BY город ORDER BY зарплата DESC) AS ранг_в_городе FROM сотрудники;
Для каждого города присваивается номер от 1 (самая высокая зарплата) до N.
RANK и DENSE_RANK:
SELECT товар, цена, RANK() OVER (ORDER BY цена DESC) AS ранг, DENSE_RANK() OVER (ORDER BY цена DESC) AS плотный_ранг FROM товары;
RANK пропускает номера при одинаковых значениях (1, 2, 2, 4), DENSE_RANK нет (1, 2, 2, 3).
SUM/AVG/COUNT с окнами — накопительные итоги:
SELECT дата_заказа, выручка, SUM(выручка) OVER (ORDER BY дата_заказа) AS накопительная_выручка FROM продажи ORDER BY дата_заказа;
Показывает, как растёт выручка день за днём.
LAG и LEAD — доступ к предыдущим и следующим строкам:
SELECT дата, продажи, LAG(продажи, 1) OVER (ORDER BY дата) AS продажи_вчера, продажи - LAG(продажи, 1) OVER (ORDER BY дата) AS изменение FROM ежедневные_продажи;
LAG(продажи, 1) возвращает значение из предыдущей строки, LEAD — из следующей. Это удобно для расчёта динамики.
FIRST_VALUE и LAST_VALUE:
SELECT дата, цена, FIRST_VALUE(цена) OVER (ORDER BY дата) AS цена_первого_дня, LAST_VALUE(цена) OVER (ORDER BY дата ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS цена_последнего_дня FROM цены_товаров;
Практический пример: топ-3 товара по выручке в каждой категории
WITH ranked_products AS (
SELECT
категория,
товар,
выручка,
RANK() OVER (PARTITION BY категория ORDER BY выручка DESC) AS ранг
FROM продажи_по_товарам
)
SELECT * FROM ranked_products WHERE ранг <= 3;
Оконные функции позволяют решать задачи, невозможные с обычным GROUP BY: сравнение с предыдущим периодом, ранжирование внутри групп, скользящие средние.
CTE (Common Table Expressions)
CTE (Common Table Expressions) — временные именованные результаты запросов, которые существуют только во время выполнения основного запроса. Они делают сложные запросы читаемыми и структурированными, заменяя вложенные подзапросы.
Базовый синтаксис:
WITH название_cte AS ( SELECT ... ) SELECT * FROM название_cte;
Простой пример:
WITH высокие_заказы AS ( SELECT * FROM заказы WHERE цена > 10000 ) SELECT COUNT(*) AS количество, AVG(цена) AS средняя_цена FROM высокие_заказы;
Вместо подзапроса в FROM мы создали читаемую конструкцию с понятным именем.
Несколько CTE в одном запросе:
WITH активные_пользователи AS ( SELECT user_id FROM пользователи WHERE статус = 'активный' ), недавние_заказы AS ( SELECT * FROM заказы WHERE дата_заказа >= CURRENT_DATE - 30 ) SELECT u.имя, COUNT(o.order_id) AS заказов_за_месяц FROM активные_пользователи au JOIN пользователи u ON au.user_id = u.user_id JOIN недавние_заказы o ON u.user_id = o.user_id GROUP BY u.имя;
Рекурсивные CTE — обход иерархий:
WITH RECURSIVE подчинённые AS ( -- Начальная точка: найти менеджера верхнего уровня SELECT employee_id, имя, manager_id, 1 AS уровень FROM сотрудники WHERE manager_id IS NULL UNION ALL -- Рекурсивная часть: найти всех подчинённых SELECT e.employee_id, e.имя, e.manager_id, p.уровень + 1 FROM сотрудники e JOIN подчинённые p ON e.manager_id = p.employee_id ) SELECT * FROM подчинённые ORDER BY уровень, имя;
Рекурсивные CTE используются для построения организационных структур, категорий товаров с подкатегориями, графов зависимостей.
CTE для разбиения сложного запроса:
WITH
продажи_по_месяцам AS (
SELECT
DATE_TRUNC('month', дата_заказа) AS месяц,
SUM(сумма) AS выручка
FROM заказы
GROUP BY месяц
),
средняя_выручка AS (
SELECT AVG(выручка) AS среднее FROM продажи_по_месяцам
)
SELECT
m.месяц,
m.выручка,
a.среднее,
ROUND((m.выручка - a.среднее) / a.среднее * 100, 2) AS отклонение_процент
FROM продажи_по_месяцам m
CROSS JOIN средняя_выручка a
ORDER BY m.месяц;
Этот запрос находит месяцы с выручкой выше или ниже средней и показывает отклонение в процентах.
Индексы и оптимизация запросов
Индексы — это структуры данных, которые ускоряют поиск информации в таблице. Без индексов СУБД сканирует всю таблицу построчно (full table scan), с индексами — находит нужные строки почти мгновенно.
Как работают индексы:
Представьте книгу без оглавления: чтобы найти нужную главу, придётся листать все страницы. Индекс — это оглавление БД, которое указывает, где находятся конкретные данные.
Создание индекса:
-- Индекс по одному полю CREATE INDEX idx_users_email ON пользователи(email); -- Составной индекс (по нескольким полям) CREATE INDEX idx_orders_user_date ON заказы(user_id, дата_заказа); -- Уникальный индекс (гарантирует отсутствие дубликатов) CREATE UNIQUE INDEX idx_users_email_unique ON пользователи(email);
Когда индексы помогают:
- WHERE с условиями на индексированные поля
- JOIN по полям с индексами
- ORDER BY по индексированным столбцам
- MIN/MAX на индексированных полях
Когда индексы НЕ нужны:
- Таблицы с малым количеством строк (до 1000)
- Поля с низкой селективностью (например, пол: М/Ж)
- Столбцы, которые часто изменяются (индексы замедляют INSERT/UPDATE)
EXPLAIN — анализ плана запроса:
EXPLAIN ANALYZE SELECT * FROM заказы WHERE user_id = 123;
EXPLAIN показывает, как СУБД выполняет запрос: использует ли индексы, сколько строк сканирует, сколько времени занимает операция.
Оптимизация запросов — лучшие практики:
- Избегайте SELECT * — выбирайте только нужные поля
- Используйте WHERE рано — фильтруйте данные до JOIN, а не после
- Индексируйте поля в JOIN и WHERE — это критично для больших таблиц
- Избегайте функций в WHERE — WHERE YEAR(дата) = 2026 не использует индекс, WHERE дата >= '2026-01-01' AND дата < '2027-01-01' использует
- LIMIT на больших выборках — если не нужны все результаты
- Используйте EXISTS вместо IN для подзапросов с большими результатами
Пример оптимизации:
Медленный запрос:
SELECT * FROM заказы WHERE EXTRACT(YEAR FROM дата_заказа) = 2026;
Быстрый запрос:
CREATE INDEX idx_orders_date ON заказы(дата_заказа); SELECT * FROM заказы WHERE дата_заказа >= '2026-01-01' AND дата_заказа < '2027-01-01';
Разница в скорости может достигать сотен раз на таблицах с миллионами строк.
Продвинутые техники: A/B-тестирование, когортный анализ
SQL используется не только для простых выборок, но и для сложной продуктовой аналитики. Две ключевые задачи для middle-аналитика — A/B-тестирование и когортный анализ.
A/B-тестирование в SQL:
A/B-тест сравнивает две версии продукта (контрольную A и тестовую B), чтобы понять, какая работает лучше. SQL помогает вычислить метрики для каждой группы.
WITH тест_группы AS (
SELECT
user_id,
CASE
WHEN user_id % 2 = 0 THEN 'A'
ELSE 'B'
END AS группа
FROM пользователи
WHERE дата_регистрации >= '2026-03-01'
),
метрики AS (
SELECT
t.группа,
COUNT(DISTINCT t.user_id) AS пользователей,
COUNT(o.order_id) AS заказов,
ROUND(COUNT(o.order_id)::NUMERIC / COUNT(DISTINCT t.user_id), 2) AS заказов_на_пользователя,
ROUND(AVG(o.сумма), 2) AS средний_чек
FROM тест_группы t
LEFT JOIN заказы o ON t.user_id = o.user_id
GROUP BY t.группа
)
SELECT * FROM метрики;
Результат покажет конверсию и средний чек для каждой группы.
Когортный анализ:
Когорта — группа пользователей, объединённых общим признаком (обычно месяцем регистрации). Когортный анализ показывает, как меняется поведение когорт со временем.
WITH когорты AS (
SELECT
user_id,
DATE_TRUNC('month', дата_регистрации) AS когорта
FROM пользователи
),
активность AS (
SELECT
k.когорта,
DATE_TRUNC('month', o.дата_заказа) AS месяц_активности,
COUNT(DISTINCT o.user_id) AS активных_пользователей
FROM когорты k
JOIN заказы o ON k.user_id = o.user_id
GROUP BY k.когорта, месяц_активности
),
размеры_когорт AS (
SELECT
когорта,
COUNT(DISTINCT user_id) AS размер_когорты
FROM когорты
GROUP BY когорта
)
SELECT
a.когорта,
a.месяц_активности,
a.активных_пользователей,
r.размер_когорты,
ROUND(a.активных_пользователей::NUMERIC / r.размер_когорты * 100, 2) AS retention_percent
FROM активность a
JOIN размеры_когорт r ON a.когорта = r.когорта
ORDER BY a.когорта, a.месяц_активности;
Этот запрос показывает retention (удержание) пользователей: какой процент когорты остаётся активным через месяц, два, три.
RFM-анализ (Recency, Frequency, Monetary):
WITH rfm AS (
SELECT
user_id,
CURRENT_DATE - MAX(дата_заказа) AS дней_с_последнего_заказа,
COUNT(*) AS количество_заказов,
SUM(сумма) AS общая_сумма
FROM заказы
GROUP BY user_id
)
SELECT
user_id,
CASE
WHEN дней_с_последнего_заказа <= 30 THEN 'Активный'
WHEN дней_с_последнего_заказа <= 90 THEN 'Засыпающий'
ELSE 'Потерянный'
END AS сегмент_по_recency,
CASE
WHEN количество_заказов >= 10 THEN 'VIP'
WHEN количество_заказов >= 3 THEN 'Лояльный'
ELSE 'Разовый'
END AS сегмент_по_frequency,
общая_сумма
FROM rfm
ORDER BY общая_сумма DESC;
RFM-сегментация помогает выделить ценных клиентов и настроить персонализированный маркетинг.
SQL в связке с Python и BI-инструментами
SQL редко используется изолированно. В реальной работе аналитик комбинирует SQL с языками программирования (Python, R) и инструментами визуализации (Tableau, Power BI, Metabase).
SQL + Python:
Python библиотеки позволяют выполнять SQL-запросы из кода и обрабатывать результаты:
import pandas as pd
import psycopg2
# Подключение к PostgreSQL
conn = psycopg2.connect(
host="localhost",
database="analytics",
user="analyst",
password="password"
)
# Выполнение SQL-запроса и загрузка в DataFrame
query = """
SELECT
дата_заказа,
SUM(сумма) AS выручка
FROM заказы
WHERE дата_заказа >= '2026-01-01'
GROUP BY дата_заказа
ORDER BY дата_заказа
"""
df = pd.read_sql(query, conn)
# Дальнейшая обработка в pandas
df['скользящее_среднее_7д'] = df['выручка'].rolling(7).mean()
conn.close()
Это позволяет использовать мощь SQL для извлечения данных и возможности Python для сложной аналитики, машинного обучения, статистических тестов.
SQL + Tableau/Power BI:
BI-инструменты подключаются к базам данных и позволяют строить интерактивные дашборды. Аналитик пишет SQL-запросы для создания витрин данных (data marts), а затем визуализирует их:
- Tableau — подключается к PostgreSQL, MySQL, BigQuery; поддерживает кастомные SQL-запросы
- Power BI — интеграция с MS SQL Server, Azure; встроенный редактор DAX и SQL
- Metabase — open-source, позволяет писать SQL и сразу строить графики
- Redash — ещё один open-source инструмент для SQL-дашбордов
Типичный workflow:
- Аналитик пишет SQL-запрос в DBeaver, проверяет результаты
- Сохраняет запрос как представление (VIEW) или витрину данных
- Подключает BI-инструмент к этой витрине
- Строит визуализации: графики, таблицы, KPI-карточки
- Публикует дашборд для команды
SQL + Jupyter Notebooks:
Jupyter поддерживает SQL через расширения (ipython-sql, JupySQL), позволяя писать SQL-запросы прямо в ячейках ноутбука:
%load_ext sql
%sql postgresql://user:password@localhost/database
%%sql
SELECT
категория,
COUNT(*) AS товаров,
AVG(цена) AS средняя_цена
FROM товары
GROUP BY категория
ORDER BY товаров DESC;
Это удобно для исследовательского анализа данных (EDA) и документирования процесса аналитики.
SQL + Apache Airflow:
Airflow — платформа для автоматизации и оркестрации задач. SQL-запросы оформляются как DAG (направленный ациклический граф), который выполняется по расписанию:
- Ежедневная загрузка данных из источника в хранилище
- Обновление витрин данных
- Отправка отчётов по email
Это уже уровень data engineer, но понимание связки SQL + автоматизация критично для роста до senior-позиций.
Где практиковаться бесплатно: Stepik, SQL Academy, SQL-EX, Karpov.Courses
Теория без практики бесполезна. Ниже — проверенные платформы для оттачивания SQL-навыков от базовых запросов до продвинутых техник.
Stepik — Интерактивный тренажёр по SQL
Бесплатный курс с автоматической проверкой задач. Начинается с SELECT, заканчивается оконными функциями и подзапросами. Удобный редактор кода прямо в браузере, мгновенная обратная связь. Подходит для абсолютных новичков.
Плюсы:
- Полностью бесплатно
- Структурированная программа от простого к сложному
- Реальная БД с данными для практики
- Сертификат по завершении
Минусы:
- Интерфейс может показаться устаревшим
- Нет живого сообщества для обсуждения
SQL Academy
Интерактивная платформа с игровым подходом. Задачи разбиты на уровни, есть рейтинг пользователей. Охватывает базовые и продвинутые темы: JOIN, GROUP BY, подзапросы, оконные функции.
Плюсы:
- Бесплатный доступ к основным урокам
- Визуальные схемы баз данных
- Понятные объяснения с примерами
- Подходит для самостоятельного изучения
Минусы:
- Некоторые продвинутые разделы платные
- Меньше задач, чем на специализированных платформах
SQL-EX.RU
Платформа с акцентом на решение практических задач. Более 100 упражнений разной сложности: от простых SELECT до сложных аналитических запросов. Подходит для тех, кто хочет углубить знания после базового курса.
Плюсы:
- Большая база задач с реалистичными сценариями
- Рейтинг решений и обсуждение подходов
- Поддержка разных СУБД (MS SQL, PostgreSQL, MySQL)
Минусы:
- Доступ к части задач платный
- Интерфейс требует привыкания
- Нет структурированной теории
Karpov.Courses — Симулятор SQL
Бесплатный тренажёр от образовательной платформы Karpov.Courses. Задачи построены на реальных данных: таблицы пользователей, заказов, курьеров. Фокус на продуктовой аналитике и метриках.
Плюсы:
- Бесплатный доступ к симулятору
- Практические задачи из реальной работы аналитика
- Подсказки и разборы решений
- Современный интерфейс
Минусы:
- Требует базовых знаний SQL
- Полный курс платный
LeetCode — раздел Database
Платформа для подготовки к собеседованиям. SQL-задачи разделены по сложности: Easy, Medium, Hard. Фокус на алгоритмических аспектах и оптимизации запросов.
Плюсы:
- Реальные задачи с собеседований в технологичных компаниях
- Обсуждения решений от сообщества
- Подготовка к интервью
Минусы:
- Большинство задач на английском
- Платная подписка для доступа ко всем задачам
HackerRank — SQL
Аналог LeetCode с разделом SQL. Задачи от базовых до продвинутых, с автоматической проверкой.
Рекомендация: начните с Stepik или SQL Academy для освоения основ, затем переходите к SQL-EX и Karpov.Courses для практики на реальных кейсах. LeetCode и HackerRank используйте для подготовки к собеседованиям.
Обзор платных курсов 2026: Skillbox, Нетология, SkillFactory, Eduson, ВШЭ
Если вам нужна структурированная программа с обратной связью от наставников и проектами в портфолио, рассмотрите платные курсы. Ниже — актуальные предложения на март 2026 года.
Skillbox — SQL для анализа данных
Длительность 2 месяца, рассрочка 6 месяцев по 8 459 рублей, полная стоимость 50 754 рубля (со скидкой 45% от 92 280 рублей). Вы освоите язык запросов SQL и сможете самостоятельно получать нужные данные, сопоставлять и анализировать их.
Программа:
- Основы баз данных и реляционных моделей
- SELECT, WHERE, JOIN, GROUP BY
- Подзапросы и CTE
- Оконные функции
- Особенности работы в MySQL, PostgreSQL, MS SQL
- Проект в портфолио
Подходит: начинающим аналитикам, маркетологам, продакт-менеджерам.
Нетология — SQL и получение данных
Длительность 2 месяца, стоимость со скидкой, оплатите курс до 24 февраля. Средняя стоимость около 22 900 рублей с рассрочкой от 2 008 рублей в месяц.
Программа:
- Основы SQL: SELECT, фильтрация, сортировка
- Объединение таблиц через JOIN
- Агрегатные функции и группировки
- Задачи по сегментации, когортам, A/B-тестированию
- Помощь с резюме и портфолио
Подходит: специалистам роста, маркетологам, аналитикам без опыта SQL.
SkillFactory — Курс по SQL для анализа данных
Длительность 7–15 недель в зависимости от темпа обучения. Стоимость варьируется, в среднем от 30 000 до 60 000 рублей.
Программа:
- Основы и продвинутый SQL
- PostgreSQL и работа с большими данными
- Оконные функции и оптимизация
- Интеграция с Python и Jupyter
- Реальные проекты из e-commerce и финтех
Подходит: аналитикам данных, будущим data scientists.
Eduson Academy — SQL с нуля для анализа данных
Длительность 3–4 недели (экспресс-формат). Стоимость от 3 552 рублей в месяц при рассрочке, полная цена около 42 624 рублей.
Программа:
- Много практики на кейсах и тренажерах, личный куратор ответит на любой вопрос, вечный доступ к курсу и обновлениям
- Основы SQL и работа с PostgreSQL
- Продвинутые запросы и аналитика
- Проектная работа
Подходит: новичкам, которым нужен быстрый старт.
ВШЭ — Курсы по анализу данных с SQL
Длительность 2 месяца. Стоимость выше среднерыночной — от 50 000 до 80 000 рублей в зависимости от программы.
Программа:
- Академический подход к базам данных
- SQL в контексте аналитики и статистики
- Проектная работа с реальными данными
- Сертификат от ВШЭ
Подходит: тем, кому важен престижный сертификат и академическая программа.
МГТУ им. Баумана
Стоимость около 52 000 рублей за 34 академических часа. Программа ориентирована на технических специалистов и разработчиков.
Сравнительная таблица курсов: цены, сроки, программы
| Школа | Длительность | Стоимость | Рассрочка | Ключевые особенности |
|---|---|---|---|---|
| Skillbox | 2 месяца | 50 754 ₽ | от 1 733 ₽/мес | MySQL, PostgreSQL, MS SQL; проект в портфолио |
| Нетология | 2 месяца | 22 900 ₽ | от 2 008 ₽/мес | Бизнес-кейсы, A/B-тестирование, когорты |
| SkillFactory | 7–15 недель | 30 000–60 000 ₽ | Индивидуально | PostgreSQL, интеграция с Python, большие данные |
| Eduson Academy | 3–4 недели | 42 624 ₽ | от 3 552 ₽/мес | Экспресс-формат, вечный доступ, личный куратор |
| ВШЭ | 2 месяца | 50 000–80 000 ₽ | Зависит от программы | Академический подход, сертификат ВШЭ |
| МГТУ Баумана | 34 ак. часа | 52 000 ₽ | Нет данных | Для технических специалистов и разработчиков |
Средняя стоимость курсов SQL в 2026 году: 43 727 рублей. Диапазон цен: от бесплатных (Stepik, SQL Academy) до 201 990 рублей за продвинутые программы с менторством.
Рекомендации по выбору:
- Ограниченный бюджет: Нетология (22 900 ₽) или бесплатные ресурсы + самообучение
- Быстрый старт: Eduson Academy (3–4 недели)
- Глубокое погружение: SkillFactory или Skillbox с проектами
- Престижный сертификат: ВШЭ или МГТУ Баумана
- Аналитика + Python: SkillFactory
Типичные ошибки начинающих и как их избежать
Изучая SQL, новички совершают предсказуемые ошибки. Зная их заранее, вы сэкономите часы отладки.
1. Путаница WHERE и HAVING
WHERE фильтрует строки до группировки, HAVING — после. Попытка использовать агрегатную функцию в WHERE приведёт к ошибке:
-- Ошибка SELECT город, COUNT(*) FROM заказы WHERE COUNT(*) > 10 GROUP BY город; -- Правильно SELECT город, COUNT(*) FROM заказы GROUP BY город HAVING COUNT(*) > 10;
2. Забытый GROUP BY при использовании агрегатов
-- Ошибка: город не в GROUP BY SELECT город, COUNT(*) FROM заказы; -- Правильно SELECT город, COUNT(*) FROM заказы GROUP BY город;
3. SELECT * в продакшене
На больших таблицах это замедляет запросы и перегружает сеть. Выбирайте только нужные поля.
4. Игнорирование NULL
NULL — это не ноль и не пустая строка. Сравнения с NULL через = не работают:
-- Не сработает SELECT * FROM пользователи WHERE email = NULL; -- Правильно SELECT * FROM пользователи WHERE email IS NULL;
5. Неправильные JOIN без условий
Забытое условие ON приводит к декартову произведению — каждая строка из первой таблицы умножается на каждую из второй:
-- Ошибка: миллионы строк вместо тысяч SELECT * FROM пользователи JOIN заказы; -- Правильно SELECT * FROM пользователи JOIN заказы ON пользователи.id = заказы.user_id;
6. Неоптимизированные запросы с подзапросами
Коррелированные подзапросы могут выполняться для каждой строки. Часто их можно заменить JOIN:
-- Медленно SELECT имя, (SELECT COUNT(*) FROM заказы WHERE user_id = пользователи.id) FROM пользователи; -- Быстрее SELECT u.имя, COUNT(o.id) FROM пользователи u LEFT JOIN заказы o ON u.id = o.user_id GROUP BY u.имя;
7. Использование DISTINCT вместо правильного JOIN
DISTINCT маскирует проблему дублирования строк. Лучше понять причину и исправить JOIN.
8. Игнорирование типов данных
-- Может не работать, если поле строковое SELECT * FROM товары WHERE id = '123'; -- Безопаснее привести тип явно SELECT * FROM товары WHERE id = 123;
Подготовка к собеседованию: задачи, кейсы, вопросы
На собеседовании на позицию аналитика данных или junior SQL-разработчика вас ждут теоретические вопросы и практические задачи. Вот что нужно знать.
Теоретические вопросы:
- Что такое первичный и внешний ключи?
- В чём разница между INNER JOIN и LEFT JOIN?
- Чем отличается WHERE от HAVING?
- Что такое индекс и зачем он нужен?
- Объясните ACID-свойства транзакций
- Что такое нормализация БД?
- В чём разница между DELETE, TRUNCATE и DROP?
- Как работает GROUP BY?
- Что такое оконные функции?
Практические задачи — типовые паттерны:
Задача 1: Найти пользователей без заказов
SELECT u.* FROM пользователи u LEFT JOIN заказы o ON u.id = o.user_id WHERE o.id IS NULL;
Задача 2: Топ-3 товара по выручке в каждой категории
WITH ranked AS (
SELECT
категория,
товар,
выручка,
RANK() OVER (PARTITION BY категория ORDER BY выручка DESC) AS ранг
FROM продажи
)
SELECT * FROM ranked WHERE ранг <= 3;
Задача 3: Найти дубликаты по email
SELECT email, COUNT(*) FROM пользователи GROUP BY email HAVING COUNT(*) > 1;
Задача 4: Рассчитать retention по месяцам
WITH первые_заказы AS (
SELECT user_id, MIN(дата_заказа) AS первый_заказ
FROM заказы GROUP BY user_id
)
SELECT
DATE_TRUNC('month', f.первый_заказ) AS когорта,
DATE_TRUNC('month', o.дата_заказа) AS месяц,
COUNT(DISTINCT o.user_id) AS активных
FROM первые_заказы f
JOIN заказы o ON f.user_id = o.user_id
GROUP BY когорта, месяц;
Задача 5: Найти второй по величине оклад
SELECT MAX(зарплата) FROM сотрудники WHERE зарплата < (SELECT MAX(зарплата) FROM сотрудники);
Или через оконные функции:
SELECT DISTINCT зарплата FROM ( SELECT зарплата, DENSE_RANK() OVER (ORDER BY зарплата DESC) AS ранг FROM сотрудники ) t WHERE ранг = 2;
Советы для собеседования:
- Проговаривайте логику вслух, объясняя каждый шаг
- Начните с простого решения, затем оптимизируйте
- Спрашивайте уточнения: какой СУБД, есть ли индексы, размер таблиц
- Используйте CTE для читаемости сложных запросов
- Покажите знание оконных функций — это уровень middle
- Подготовьте 2–3 проекта в портфолио с SQL-запросами
Ресурсы для тренировки:
- LeetCode Database — задачи уровня FAANG
- HackerRank SQL — от Easy до Hard
- SQL-EX — российская платформа с реалистичными кейсами
- StrataScratch — реальные вопросы с собеседований
Сертификации: Oracle, Microsoft, Databricks
Сертификация подтверждает уровень владения SQL и повышает шансы при трудоустройстве, особенно в корпоративном сегменте.
Oracle Database SQL Certified Associate
Официальная сертификация Oracle для SQL-разработчиков. Экзамен проверяет знания:
- SELECT, JOIN, подзапросы
- GROUP BY, агрегатные функции
- DDL (CREATE, ALTER, DROP)
- DML (INSERT, UPDATE, DELETE)
- Индексы, представления, последовательности
Стоимость: около 17 000 рублей за экзамен. Подготовка занимает 2–3 месяца при наличии базовых знаний SQL.
Кому подходит: разработчикам БД, администраторам, аналитикам, работающим с Oracle Database.
Microsoft Certified: Azure Data Fundamentals (DP-900)
Базовая сертификация Microsoft по работе с данными в облаке Azure. Включает SQL, но также NoSQL и аналитические сервисы.
Темы:
- Реляционные БД и SQL
- Azure SQL Database
- Основы аналитики данных
- Data warehousing
Стоимость: около 5 000–7 000 рублей. Экзамен на английском, 60 минут.
Кому подходит: аналитикам и разработчикам, работающим в Microsoft-экосистеме.
Databricks Certified Associate Developer for Apache Spark
Сертификация для работы с большими данными через Spark SQL.
Темы:
- Spark SQL синтаксис
- DataFrames и таблицы
- Оптимизация запросов
- Delta Lake
Стоимость: около 18 000 рублей. Требует понимания распределённых систем.
Кому подходит: data engineers, аналитикам больших данных.
Стоит ли получать сертификацию?
Плюсы:
- Повышает доверие работодателей
- Структурирует знания
- Даёт преимущество при найме в крупных компаниях
- Подтверждает уровень владения конкретной СУБД
Минусы:
- Дорого (от 17 000 рублей)
- Требует времени на подготовку
- Многие работодатели смотрят на портфолио, а не сертификаты
Рекомендация: Если вы работаете в корпоративной среде (Oracle, MS SQL Server) или планируете переход в крупную компанию — сертификация полезна. Для стартапов и продуктовых компаний важнее реальные проекты и опыт решения бизнес-задач.
Roadmap обучения: от новичка до Middle-специалиста
Чёткий план помогает не распыляться и двигаться последовательно от основ к продвинутым техникам. Вот проверенный roadmap.
Этап 1: Основы (2–4 недели)
- Изучите структуру реляционных БД: таблицы, строки, столбцы, ключи
- Освойте SELECT, WHERE, ORDER BY, LIMIT
- Научитесь фильтровать данные: операторы сравнения, LIKE, BETWEEN, IN
- Установите DBeaver, подключитесь к тестовой БД
- Решите 20–30 задач на Stepik или SQL Academy
Этап 2: Объединения и группировки (2–3 недели)
- Изучите все типы JOIN: INNER, LEFT, RIGHT, FULL OUTER
- Освойте GROUP BY и агрегатные функции: COUNT, SUM, AVG, MIN, MAX
- Поймите разницу WHERE и HAVING
- Решите 30–50 задач с JOIN и группировками на SQL-EX
Этап 3: Изменение данных (1 неделя)
- INSERT, UPDATE, DELETE
- Транзакции: BEGIN, COMMIT, ROLLBACK
- CREATE TABLE, ALTER TABLE, DROP TABLE
- Создайте собственную тестовую БД, заполните данными
Этап 4: Подзапросы и CTE (2–3 недели)
- Подзапросы в WHERE, SELECT, FROM
- EXISTS, NOT EXISTS, ANY, ALL
- CTE (WITH) для структурирования сложных запросов
- Рекурсивные CTE
- Решите 20–30 задач среднего уровня
Этап 5: Оконные функции (2–3 недели)
- ROW_NUMBER, RANK, DENSE_RANK
- LAG, LEAD для работы с временными рядами
- SUM/AVG с PARTITION BY
- FIRST_VALUE, LAST_VALUE
- Решите 20–30 задач на оконные функции
Этап 6: Оптимизация и продвинутые темы (2–4 недели)
- Индексы: создание, типы, когда применять
- EXPLAIN для анализа плана запроса
- Оптимизация JOIN и подзапросов
- Партиционирование таблиц
- Материализованные представления
Этап 7: Практические проекты (4–6 недель)
- Создайте аналитический проект: найдите открытый датасет (Kaggle, GitHub)
- Загрузите данные в PostgreSQL
- Постройте витрины данных для анализа: продажи по месяцам, топ-клиенты, retention
- Реализуйте когортный анализ, RFM-сегментацию
- Оформите проект на GitHub с описанием задачи и SQL-запросами
Этап 8: Интеграция с другими инструментами (по желанию, 2–3 недели)
- SQL + Python: библиотеки psycopg2, SQLAlchemy, pandas
- SQL + Tableau/Power BI: создание дашбордов
- SQL + Jupyter Notebooks для аналитических отчётов
Общее время до уровня Middle: 4–6 месяцев при темпе 10–15 часов в неделю. Ключевой момент — регулярная практика. Лучше 30 минут каждый день, чем 5 часов раз в неделю.
Чек-лист Middle SQL-аналитика:
- Уверенно пишете SELECT, JOIN, GROUP BY без подсказок
- Используете оконные функции для сложных аналитических задач
- Применяете CTE для структурирования запросов
- Понимаете планы выполнения запросов (EXPLAIN)
- Создали 2–3 проекта с реальными данными
- Можете объяснить разницу между RANK, DENSE_RANK, ROW_NUMBER
- Решили 100+ задач на SQL-платформах
Заключение: практика, проекты, портфолио
SQL — инструмент, который раскрывается только через практику. Теория даёт основу, но уверенность приходит после сотен написанных запросов и десятков решённых аналитических задач.
Три принципа эффективного обучения SQL:
1. Практика важнее теории
Не застревайте в бесконечном изучении курсов. Освоили SELECT и WHERE? Сразу переходите к задачам на Stepik. Изучили JOIN? Решайте кейсы на SQL-EX. Мышечная память в программировании формируется через повторение.
2. Реальные проекты дают больше, чем учебные задачи
После базового уровня найдите открытый датасет (продажи, пользователи, транзакции) и постройте на его основе аналитический проект:
- Загрузите данные в PostgreSQL
- Сформулируйте 5–7 бизнес-вопросов
- Напишите SQL-запросы для ответов
- Оформите результаты в Jupyter Notebook или Google Colab
- Опубликуйте на GitHub
Это портфолио, которое покажет работодателю вашу способность решать реальные задачи.
3. Обратная связь ускоряет рост
Если учитесь самостоятельно, присоединяйтесь к сообществам: Телеграм-каналы по аналитике данных, форумы SQL.ru, Reddit r/SQL. Показывайте свои запросы, спрашивайте, как их улучшить. Платные курсы с менторами дают структурированную обратную связь, но её можно получить и бесплатно через комьюнити.
Следующие шаги после освоения SQL:
- Углубите знания одной СУБД: станьте экспертом PostgreSQL или MS SQL Server
- Изучите Python для аналитики: pandas, numpy, matplotlib — стандартный стек аналитика
- Освойте BI-инструменты: Tableau, Power BI, Metabase для визуализации
- Изучите Git: для версионирования SQL-скриптов и совместной работы
- Попробуйте работу с большими данными: Spark SQL, ClickHouse, BigQuery
SQL — это не финальная точка, а фундамент для карьеры в данных. С этим навыком вы можете развиваться в сторону data analyst, business intelligence analyst, analytics engineer, data engineer или даже data scientist.
Главное — начать. Установите DBeaver, подключитесь к тестовой базе, напишите первый SELECT. Через три месяца регулярной практики вы удивитесь, насколько далеко продвинулись.
Проверьте себя
5 вопросов по материалу статьи
1. Что такое SQL?
2. Какой из следующих специалистов использует SQL для анализа поведения пользователей?
3. Какой тип базы данных является самым распространённым?
4. Какой из следующих языков не является языком структурированных запросов?
5. Какой медианный ежемесячный доход аналитиков данных в России в 2026 году?




