SQL

SQL тренажер с задачами: SELECT, JOIN, GROUP BY на практике

Эта тренировка закрывает три базовых блока SQL: выбрать строки через SELECT, связать таблицы через JOIN и собрать показатели через GROUP BY. Такой набор нужен почти в любой работе с данными

Хорошая SQL-практика строится не вокруг угадывания синтаксиса, а вокруг вопроса к данным. Сначала нужно понять, какие таблицы участвуют, какая связь между ними, что фильтруем, что группируем и какой результат можно проверить глазами

По этой теме полезно отдельно посмотреть SQL тренажер: как практиковаться в запросах, чтобы расширить контекст и сравнить подходы

По этой теме полезно отдельно посмотреть SQL Academy тренажер: как практиковаться, чтобы расширить контекст и сравнить подходы

Таблицы для тренировки

В примерах будем опираться на четыре таблицы:

  • customers(id, name, city)
  • orders(id, customer_id, total, created_at, status)
  • products(id, title, category, price)
  • order_items(order_id, product_id, quantity)

Если вы тренируетесь в онлайн-тренажере, не копируйте схему буквально. Сначала найдите похожие таблицы в своей задаче: кто покупает, что покупает, где сумма, где дата, где связь между таблицами

Как работать с задачами

Перед каждым запросом запишите ожидаемый результат словами. Например: показать заказы дороже 5000, найти клиентов без заказов, посчитать продажи по городам

После запуска не смотрите только на отсутствие ошибки. Проверьте количество строк, сортировку, пустые случаи и дубли. Именно на таких проверках становится видно, понимаете ли вы запрос

Задачи с решениями

Задача 1. Выбрать дорогие заказы

Найдите заказы дороже 5000 и отсортируйте их от большей суммы к меньшей

Решение:

SELECT id, customer_id, total
FROM orders
WHERE total > 5000
ORDER BY total DESC;

Проверка: добавьте заказ ровно на 5000 и убедитесь, что он не попал в выборку

Задача 2. Посчитать заказы по клиентам

Покажите customer_id и количество заказов для каждого клиента

Решение:

SELECT customer_id, COUNT(*) AS orders_count
FROM orders
GROUP BY customer_id
ORDER BY orders_count DESC;

Проверка: сравните количество строк с числом клиентов, у которых есть хотя бы один заказ

Задача 3. Найти клиентов без заказов

Выведите клиентов, у которых нет записей в таблице заказов

Решение:

SELECT c.id, c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;

Проверка: добавьте клиента без заказа и проверьте, что он появился в результате

Задача 4. Сумма продаж по городам

Посчитайте выручку по городам клиентов

Решение:

SELECT c.city, SUM(o.total) AS revenue
FROM customers c
JOIN orders o ON o.customer_id = c.id
GROUP BY c.city
ORDER BY revenue DESC;

Проверка: проверьте город, где есть несколько клиентов и несколько заказов

Задача 5. Товары с самым большим спросом

Найдите товары, которые чаще всего встречаются в заказах

Решение:

SELECT p.title, SUM(oi.quantity) AS sold
FROM order_items oi
JOIN products p ON p.id = oi.product_id
GROUP BY p.id, p.title
ORDER BY sold DESC
LIMIT 10;

Проверка: проверьте товар с одинаковым количеством продаж у двух позиций

Задача 6. Средний чек только по оплаченным заказам

Посчитайте средний чек, но не учитывайте отмененные заказы

Решение:

SELECT AVG(total) AS avg_paid_order
FROM orders
WHERE status = 'paid';

Проверка: добавьте отмененный заказ на большую сумму и убедитесь, что средний чек не изменился

Задача 7. Фильтр групп через HAVING

Покажите города, где выручка выше 10000

Решение:

SELECT c.city, SUM(o.total) AS revenue
FROM customers c
JOIN orders o ON o.customer_id = c.id
GROUP BY c.city
HAVING SUM(o.total) > 10000;

Проверка: объясните, почему условие нельзя поставить в WHERE

Задача 8. Уникальные клиенты по городам

Посчитайте количество клиентов в каждом городе

Решение:

SELECT city, COUNT(DISTINCT id) AS customers_count
FROM customers
GROUP BY city
ORDER BY customers_count DESC;

Проверка: проверьте город с одним клиентом и город с несколькими клиентами

Задача 9. Заказы с названием клиента

Выведите заказы вместе с именем клиента

Решение:

SELECT o.id, c.name, o.total
FROM orders o
JOIN customers c ON c.id = o.customer_id
ORDER BY o.created_at DESC;

Проверка: проверьте, что заказ без клиента не попадет при JOIN

Как читать готовый запрос

Начинайте с FROM: откуда берутся данные. Потом смотрите JOIN, потому что именно там часто теряются строки или появляются дубли. После этого переходите к WHERE, GROUP BY, HAVING, SELECT и ORDER BY

Если запрос длинный, запускайте его слоями: сначала одна таблица, затем соединение, затем фильтр, затем группировка. Такой порядок быстрее показывает место ошибки

Типичные ошибки

  • использовать SELECT *, когда нужны конкретные поля
  • забывать условие соединения в JOIN
  • фильтровать агрегаты через WHERE, хотя нужен HAVING
  • не проверять клиентов или товары без связанных записей
  • считать строки вместо уникальных значений
  • не смотреть на NULL

Почти любую SQL-задачу можно упростить до маленькой проверки. Если результат странный, временно уберите часть условий и посмотрите, на каком шаге данные изменились не так

План практики

  1. Напишите пять запросов SELECT с разными полями
  2. Добавьте фильтры WHERE
  3. Потренируйте ORDER BY и LIMIT
  4. Перейдите к GROUP BY и агрегатам
  5. Добавьте JOIN
  6. Проверьте LEFT JOIN и отсутствующие связи
  7. Перепишите один длинный запрос в несколько понятных шагов

Контрольный сценарий

Соберите один отчет, где используются все три ключевых приема: SELECT, JOIN и GROUP BY. Например, нужно увидеть выручку и количество заказов по городам

SELECT
  c.city,
  COUNT(o.id) AS orders_count,
  SUM(o.total) AS revenue
FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE o.status = 'paid'
GROUP BY c.city
ORDER BY revenue DESC;

Разберите его по слоям. SELECT задает вид результата, JOIN подтягивает город клиента, WHERE оставляет оплаченные заказы, GROUP BY собирает строки по городам, ORDER BY ставит самые важные города сверху

Как усложнить отчет

Добавьте средний чек, минимальный заказ и фильтр городов с выручкой выше 10000

SELECT
  c.city,
  COUNT(o.id) AS orders_count,
  SUM(o.total) AS revenue,
  AVG(o.total) AS avg_order
FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE o.status = 'paid'
GROUP BY c.city
HAVING SUM(o.total) > 10000
ORDER BY revenue DESC;

Если этот запрос понятен, базовая связка SELECT + JOIN + GROUP BY уже стала рабочим инструментом

Финальная самопроверка

Перед тем как считать задачу решенной, проверьте четыре вещи. Первая — не потерялись ли строки при соединении таблиц. Если в условии важны клиенты без заказов или товары без продаж, обычный JOIN может скрыть нужные строки. Вторая — не появились ли дубли после соединения. Один заказ с несколькими позициями может размножить строки, и обычный COUNT(*) начнет считать не то

Третья проверка — границы фильтра. Если написано «от 5000», уточните, входит ли сама сумма 5000. Для этого есть разница между > и >=. Четвертая проверка — смысл итоговой строки. После GROUP BY одна строка результата должна соответствовать одной группе: клиенту, городу, дню, товару или категории

Мини-задание для закрепления: возьмите любой запрос из статьи и перепишите его в два варианта — сначала через обычный JOIN, потом через LEFT JOIN. Сравните количество строк и объясните, почему результат отличается. Это упражнение быстро показывает, понимаете ли вы связь между таблицами

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x