Каждый день одно и то же. Открываешь клиент базы данных, чтобы что-то проверить, посчитать или найти. И снова пишешь почти тот же SELECT, что и вчера, с тем же WHERE и JOIN. Знакомо?
SQL в большинстве случаях не требует сложные 100-строчные запросы с вложенными подзапросами на три уровня глубины. Чаще всего нам нужны простые, отточенные и, главное, эффективные конструкции.
В этой статье я собрал 7 таких запросов-«рабочих лошадок». Это не какой-то там справочник, а готовая шпаргалка для реальных задач.
Прежде чем перейти к запросам, запомните главное правило любого UPDATE или DELETE: всегда сначала пишите SELECT с теми же условиями WHERE.
Серьёзно, всегда. Это убережёт вас от случайного изменения или удаления не тех данных. Один мой знакомый в начале карьеры однажды чуть не отправил в архив несколько гигабайт production-данных из-за неверного условия. С тех пор он, да и я тоже делаем так:
-- Шаг 1: Сначала СМОТРИМ, что будем обновлять/удалять SELECT * FROM orders WHERE status = 'test'; -- Шаг 2: Убедившись, что выборка корректна, заменяем на UPDATE/DELETE DELETE FROM orders WHERE status = 'test';
Теперь, когда этот критически важный ритуал усвоен, перейдём к тем самым «рабочим лошадкам».
❯ 1. Ежедневный мониторинг
Как обычно, первым делом с утра нам нужно проверить, что система жива, данные поступают, ничего не сломалось ночью. Без ORDER BY и LIMIT можно случайно выгрузить всю таблицу и подвесить клиент, чего явно нам не хотелось бы.
SELECT id, status, created_at, amount FROM latest_transactions WHERE status = 'processed' ORDER BY created_at DESC LIMIT 10;
Ключевая привычка — всегда использовать ORDER BY для детерминированности и LIMIT для безопасности.
Допустим, вы увидели, что данные поступают. Что дальше? Обычно следом просят свестить итоги и подготовить отчет.
❯ 2. Агрегация данных
Самый частый запрос для любого отчёта. Посчитать количество, сумму, среднее значение по группам. Здесь на первый план выходят GROUP BY и агрегатные функции.
SELECT user_id, COUNT(*) AS total_orders, SUM(amount) AS total_revenue FROM orders WHERE created_at >= '2024-01-01' GROUP BY user_id HAVING SUM(amount) > 1000 ORDER BY total_revenue DESC;
Считает выручку по каждому пользователю с начала года, но показывает только «VIP-клиентов», принесших больше 1000 единиц. Запомните: WHERE фильтрует строки догруппировки, а HAVING — после.
Готовя отчеты, но вы вдруг замечаете аномалии: некоторые цифры не сходятся. Есть подозрение на дубликаты.
❯ 3. Охота за дубликатами
Дубликаты — вечная головная боль. Они появляются из-за ошибок в логике приложения, сбоев и багов. Их нужно уметь быстро находить. Спасет GROUP BY и HAVING.
SELECT email, COUNT(*) AS duplicate_count FROM users GROUP BY email HAVING COUNT(*) > 1;
Находит все email-адреса, которые встречаются в таблице пользователей больше одного раза. Это отправная точка для «зачистки».
Дубликаты найдены. Чтобы принять осмысленное решение по ним, нужно больше информации. Пора заглянуть в связанные таблицы.
❯ 4. Объединение данных из нескольких таблиц
Данные в нормализованной базе всегда разбросаны. Чтобы получить полную картину, нужны JOIN-ы.
SELECT u.first_name, u.last_name, o.order_date, o.total_amount, p.product_name FROM users u INNER JOIN orders o ON u.id = o.user_id LEFT JOIN products p ON o.product_id = p.id WHERE u.country = 'Germany' ORDER BY o.order_date DESC;
Главное — не запутаться в их типах.
Их всего 3:INNER JOIN - только совпадающие записи с обеих сторон
LEFT JOIN - все записи из левой таблицы + совпадения справа
RIGHT JOIN - все записи из правой таблицы + совпадения слева
Объединив данные, вы обнаруживаете сложную закономерность: нужно найти записи, которые соответствуют условию на основе других данных.
❯ 5. Запросы в запросах
Когда простых условий WHERE уже недостаточно, на помощь приходят подзапросы. Они позволяют вложить один запрос в другой для сложной фильтрации.
SELECT * FROM products WHERE price > ( SELECT AVG(price) FROM products WHERE category_id = 5 ) AND category_id = 5;
Находит все товары в категории 5, цена которых выше средней по этой же категории. Идеально для поиска аномалий и выбросов.
Проанализировав данные, вы понимаете, что пора не просто смотреть, а что-то менять. Самое опасное — модификация данных.
❯ 6. Модификация данных с умом
Вот мы и дошли до самого опасного — UPDATE и DELETE. Здесь правило только одно: семь раз отмерь, один раз выполни. Всегда начинай с SELECT.
-- ШАГ 1: Сначала смотрим, что будем менять SELECT * FROM users WHERE last_login < '2024-01-01' AND active = true; -- ШАГ 2: Только затем выполняем UPDATE (и лучше в транзакции!) BEGIN; UPDATE users SET active = false WHERE last_login < '2024-01-01' AND active = true; -- Смотрим, что получилось, и только потом COMMIT или ROLLBACK COMMIT;
Данные обновлены. Теперь нужно проанализировать результат в разрезе времени или групп, не схлопывая строки. Обычного GROUP BY уже мало.
❯ 7. Оконные функции
Финальный аккорд — мощные оконные функции (OVER, PARTITION BY). Они позволяют делать агрегацию без группировки, сохраняя все исходные строки.
SELECT product_id, sale_date, daily_revenue, SUM(daily_revenue) OVER ( PARTITION BY product_id ORDER BY sale_date ) AS cumulative_revenue FROM sales ORDER BY product_id, sale_date;
Для каждого товара рассчитывает нарастающий итог выручки по дням. В отличие от GROUP BY, мы видим каждую продажу, а не только итог.
Вот и все. Этих 7 запросов хватит, чтобы уверенно чувствовать себя в 90% рабочих ситуаций с SQL. Они покрывают весь цикл работы с данными: от ежедневного мониторинга до сложной аналитики и аккуратной модификации.
Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале ↩
📚 Читайте также:
➤ Технологии из прошлого: телетайп. Разбираемся в устройстве, воскрешаем старый аппарат
➤ Болезнь Крона, осы-паразиты и «больной нытик из Цюриха»: что стоит за главной сценой «Чужого»
Перед оплатой в разделе «Бонусы и промокоды» в панели управления активируйте промокод и получите кэшбэк на баланс.

