Эта статья — практическое введение в основы SQL для начинающих и тех, кто хочет систематизировать опыт. Мы разберёмся, что такое SQL, зачем он нужен, как писать простые и полезные запросы, и главное — как начать думать на SQL, чтобы уверенно решать реальные задачи.

1. Что такое SQL и зачем он нужен?
SQL (Structured Query Language) — это язык для общения с реляционными базами данных. Представьте:
- Интернет-магазин: нужно показать каталог, найти товары по фильтрам, оформить заказ, посчитать выручку за день.
- Соцсеть: показать ленту, найти друзей из одного города, посчитать активных пользователей.
- CRM: выбрать клиентов без активных заказов, обновить статусы сделок, построить воронку продаж.
Во всех этих случаях данные лежат в таблицах. SQL позволяет читать, добавлять и изменять данные, а также агрегировать их для отчётов: «Сколько заказов вчера?», «Средний чек по городу Москва?», «Какие товары не покупали месяц?».
2. Основные концепции
- Таблица — как лист Excel: строки и столбцы.
- Столбец — отдельный атрибут (имя, цена, город).
- Строка — одна запись (конкретный пользователь, заказ, товар).
- Первичный ключ (PK) — уникальный идентификатор строки (например,
id). - Связи между таблицами строятся по ключам:
- 1 ко многим: пользователь → заказы (
users.id→orders.user_id) - многие ко многим: заказ ↔ товары через таблицу связей (
order_items)
- 1 ко многим: пользователь → заказы (
Мини-схема, с которой будем работать:
-- Пользователи
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT,
city TEXT
);
-- Товары
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT,
price DECIMAL(10,2)
);
-- Заказы (шапка)
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER,
created_at DATE,
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- Позиции заказа (содержимое)
CREATE TABLE order_items (
order_id INTEGER,
product_id INTEGER,
qty INTEGER,
price DECIMAL(10,2), -- цена на момент покупки
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
3. Базовые команды (с простыми примерами)
SELECT — «показать»
-- Все пользователи с именем и городом
SELECT id, name, city
FROM users;
WHERE — «фильтровать»
-- Пользователи из Москвы
SELECT id, name
FROM users
WHERE city = 'Москва';
INSERT — «добавить запись»
INSERT INTO users (id, name, city)
VALUES (101, 'Алексей', 'Казань');
UPDATE — «изменить запись»
-- Важно: всегда уточняйте WHERE!
UPDATE users
SET city = 'Санкт-Петербург'
WHERE id = 101;
DELETE — «удалить запись»
-- Удалим тестового пользователя (сначала проверьте SELECT-ом!)
DELETE FROM users
WHERE id = 101;
Немного полезной аналитики:
-- Количество пользователей по городам (агрегация + группировка)
SELECT city, COUNT(*) AS users_count
FROM users
GROUP BY city
ORDER BY users_count DESC;
4. Как «думать» на SQL
SQL — декларативный: вы описываете, *что* хотите получить, а не *как* по шагам это посчитать. Помогает мыслить наборами:
- Отбираем строки (FROM + WHERE): какие записи нам нужны?
- Соединяем таблицы (JOIN): какие атрибуты подтянуть из других таблиц?
- Группируем и считаем (GROUP BY + агрегаты
COUNT/AVG/SUM): какие показатели хотим получить? - Фильтруем агрегаты (HAVING): например, «только города с ≥ 100 пользователями».
- Сортируем и ограничиваем (ORDER BY + LIMIT).
Пример: «средний чек по каждому пользователю за август»:
SELECT u.id, u.name,
AVG(oi.qty * oi.price) AS avg_order_value
FROM users u
JOIN orders o ON o.user_id = u.id
JOIN order_items oi ON oi.order_id = o.id
WHERE o.created_at >= DATE '2025-08-01'
AND o.created_at < DATE '2025-09-01'
GROUP BY u.id, u.name
ORDER BY avg_order_value DESC
LIMIT 10;
5. Практика: 3 коротких упражнения
Можете решать устно, а можете выполнить в любой «песочнице» (например, SQLite или онлайн-песочнице). Схема — как выше.
Упражнение 1. «Найди всех пользователей из Москвы, отсортируй по имени»
Задача: вывести id, name пользователей, у кого city = 'Москва', по алфавиту.
Подсказка/решение:
SELECT id, name
FROM users
WHERE city = 'Москва'
ORDER BY name ASC;
Упражнение 2. «Посчитай средний чек заказа»
Задача: для каждого заказа вернуть order_id и его сумму (количество × цена по каждой позиции, потом сложить), затем посчитать средний чек по всем заказам.
Подсказка/решение (2 шага):
-- 1) Сумма по каждому заказу
WITH order_totals AS (
SELECT oi.order_id,
SUM(oi.qty * oi.price) AS total
FROM order_items oi
GROUP BY oi.order_id
)
-- 2) Средний чек по всем заказам
SELECT AVG(total) AS avg_order_value
FROM order_totals;
Упражнение 3. «Топ-3 города по количеству пользователей»
Задача: посчитать пользователей по городам и показать три города-лидера.
Подсказка/решение:
SELECT city, COUNT(*) AS users_count
FROM users
GROUP BY city
ORDER BY users_count DESC
LIMIT 3;
6. Дальнейшие шаги: что изучать и как тренироваться
Темы по возрастанию пользы:
- JOIN:
INNER,LEFT, режеRIGHT,FULL. Как не плодить дубликаты и не терять строки. - Подзапросы и CTE (
WITH) — разбиваем сложные задачи на части. - Оконные функции (
ROW_NUMBER,RANK,SUM() OVER(...)) — скользящие суммы, доли, топ-N в разрезах без группировки. - Индексы — как ускоряют
WHERE/JOIN, чем чреваты дляINSERT/UPDATE, карточность и выборка столбцов. - Нормализация — как проектировать таблицы без дублирования и аномалий.
- Транзакции — целостность данных (
BEGIN/COMMIT/ROLLBACK). - План запроса — понимать, *почему* запрос работает быстро/медленно.
Как тренироваться (бесплатно):
- Интерактивный онлайн курс по SQL + тренажер от SQL Academy (на русском)
- SQLite (в том числе локально), DB Browser for SQLite.
- Онлайн-песочницы вроде DB Fiddle.
- Интерактивные тренажёры по типу SQLBolt.
- Придумайте маленький набор данных «из жизни» (расходы, книги, спорт) и задайте к нему вопросы: так прокачивается логика запросов.
7. Распространённые ошибки новичков и как их избежать
UPDATE/DELETEбезWHERE.Как избежать: сначала пишите
SELECT ... WHERE ...и проверяйте результат, потом заменяйте наUPDATE/DELETE.SELECT *всегда и везде.Как избежать: выбирайте конкретные столбцы — так запросы понятнее и быстрее.
- Путаница
WHEREиHAVING.Как избежать:
WHEREфильтрует строки до группировки,HAVING— группы послеGROUP BY. - Игнорирование
NULL.Как избежать: помните, что
NULL— «неизвестно». Сравнения= NULLне работают, используйтеIS NULL/IS NOT NULLи функцииCOALESCE. - Лишние или «ломающие» JOIN-ы.
Как избежать: проверяйте кратность связей. Если внезапно растёт количество строк — смотрите, не получился ли «декартов» эффект.
- Оптимизация без плана запроса.
Как избежать: перед «тюнингом» посмотрите план (
EXPLAIN). Возможно, нужен индекс или переписать условие. - Мыслить «построчно», а не «набором».
Как избежать: в SQL вы работаете с целыми наборами. Заменяйте пошаговые циклы на операции фильтрации, группировки и оконные функции.
Итог
Теперь вы понимаете, что такое SQL и зачем он нужен в реальных продуктах — от интернет-магазинов до CRM. Начните с простых выборок и фильтрации, постепенно добавляйте группировки и JOIN-ы. Регулярная практика — лучший способ как научиться SQL: решайте небольшие задачи, читайте планы запросов и не бойтесь экспериментов в «песочнице». Вы уже на пути к тому, чтобы осознанно работать с данными и чувствовать себя уверенно.