Что такое 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. Через три месяца регулярной практики вы удивитесь, насколько далеко продвинулись.





