Подсчёт и фильтрация групп
Находите группы, достигающие порога: классический вопрос о клиентах с более чем N заказами.
«Подсчёт и фильтрация групп» — бесплатный урок SQL Interview Prep на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Interview Prep, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Interview Prep содержит 4 уроков всего.
Самый распространённый вопрос о группировке
«Найдите клиентов, у которых больше N заказов» — классическая задача на собеседовании по GROUP BY. Вариации встречаются постоянно: продукты, проданные более X раз; отделы, в которых работает не менее Y сотрудников; дни, когда было более Z входов в систему.
Во всех случаях используется один и тот же шаблон: сгруппировать, подсчитать, затем отфильтровать группы с помощью HAVING.
Шаг первый: подсчёт в каждой группе
Начните с подсчёта строк внутри каждой группы. Выполните группировку по ключу, определяющему «клиента» или «продукт», затем примените COUNT(*).
В результате Вы получите одну строку на группу с указанием её размера. Фильтрации ещё не было — Вы только измерили размер каждой группы.
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id;Шаг второй: фильтрация с помощью HAVING
Теперь оставьте только группы, соответствующие порогу. Условие относится к агрегатной функции, поэтому оно должно находиться в HAVING, а не в WHERE.
Понимайте это так: «сгруппируйте заказы по клиентам, затем оставьте клиентов, у которых количество заказов превышает пять». Это полный ответ на классическую задачу.
SELECT customer_id, COUNT(*) AS order_count
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5;Подсчёт уникальных значений и всех строк
Внимательно следите за формулировкой. Для задачи «найдите клиентов, заказавших более 3 разных продуктов» требуется COUNT(DISTINCT product_id), а не COUNT(*).
COUNT(*)подсчитывает строки в группе.COUNT(DISTINCT col)подсчитывает уникальные значения, отличные от NULL.
Интервьюеры добавляют в условие слова «разных» или «уникальных», чтобы проверить, воспользуетесь ли Вы DISTINCT.
SELECT customer_id, COUNT(DISTINCT product_id) AS distinct_products
FROM orders
GROUP BY customer_id
HAVING COUNT(DISTINCT product_id) > 3;Фильтрация по SUM вместо COUNT
Та же структура подходит для сумм. Задача «найдите клиентов, которые потратили в общей сложности более 1000» требует группировки по клиенту и фильтрации по SUM(amount).
Условие HAVING может задаваться любой агрегатной функцией: COUNT, SUM, AVG, MAX, MIN. Понимание показателя в формулировке задачи подсказывает, по какой агрегатной функции нужно выполнять фильтрацию.
SELECT customer_id, SUM(amount) AS total_spent
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 1000;Несколько условий для группы
HAVING может объединять условия с помощью AND/OR, в том числе условия для разных агрегатных функций. Например, «клиенты, у которых более 5 заказов AND средняя стоимость заказа превышает 100» задаются одним предложением HAVING.
Каждое условие ссылается на собственную агрегатную функцию; все условия вычисляются после группировки. Это показывает, что Вы умеете понятно выражать составные бизнес-правила.
SELECT customer_id,
COUNT(*) AS orders,
AVG(amount) AS avg_order
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5 AND AVG(amount) > 100;Совместное использование WHERE и HAVING
Часто строки нужно отфильтровать до подсчёта. Условие «среди заказов текущего года найти клиентов, у которых более 5 заказов» использует WHERE для даты и HAVING для количества.
Сначала WHERE уменьшает набор строк, затем выполняются группировка и проверка порога в HAVING. Умение правильно использовать оба предложения в одном запросе показывает уровень специалиста среднего звена.
SELECT customer_id, COUNT(*) AS orders_this_year
FROM orders
WHERE order_date >= '2024-01-01'
GROUP BY customer_id
HAVING COUNT(*) > 5;Поиск дубликатов
Близкая задача — «найдите повторяющиеся адреса электронной почты». Выполните группировку по столбцу, который должен быть уникальным, и оставьте группы с количеством строк больше одного.
Этот простой шаблон обнаруживает дублирующиеся ключи, повторные транзакции и любые значения, которые встречаются чаще допустимого. Интервьюеры задают такую задачу, чтобы проверить, воспринимаете ли Вы группировку как инструмент поиска дубликатов.
SELECT email, COUNT(*) AS times_seen
FROM users
GROUP BY email
HAVING COUNT(*) > 1;Группы с точным количеством
Пороговые значения не всегда задаются условием «больше». Для запроса «клиенты ровно с одним заказом» используется HAVING COUNT(*) = 1, а для условия «как минимум 3» — >= 3.
Обращайте внимание на слово, обозначающее границу, в формулировке: «больше», «как минимум», «ровно», «меньше». Каждому из них соответствует свой оператор сравнения, и на собеседованиях проверяют точность такого выбора.
-- One-time customers
SELECT customer_id, COUNT(*) AS orders
FROM orders
GROUP BY customer_id
HAVING COUNT(*) = 1;Возврат только ключей
Иногда в условии нужны только подходящие идентификаторы, а не количества — часто для передачи в другой запрос. Вы по-прежнему группируете строки и фильтруете группы, но выбираете в SELECT только ключ.
Затем этот результат можно обернуть в подзапрос IN или использовать в соединении, чтобы получить все записи для этих клиентов. Знание такой композиции — признак высокого уровня владения SQL.
SELECT customer_id
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5;План решения задач на собеседовании
Для любого вопроса о «группах, соответствующих порогу» вслух пройдите четыре шага: (1) определите ключ группировки, (2) выберите агрегатный показатель, (3) определите оператор сравнения по формулировке, (4) поместите фильтры строк в WHERE, а фильтр по агрегату — в HAVING.
Этот шаблон решает весь класс задач на подсчёт и фильтрацию.
Быстрая проверка
Выберите правильный запрос для этой формулировки.
Итоги
Шаблон: сгруппируйте данные по ключу, примените агрегат и отфильтруйте группы с помощью HAVING. Это решает задачи о «более чем N заказах», клиентах с наибольшими расходами, дубликатах и клиентах с единственным заказом.
- Используйте
COUNT(*)для подсчёта строк, аCOUNT(DISTINCT col)— для уникальных значений. - Сопоставляйте оператор сравнения с формулировкой условия.
- Фильтры строк помещайте в WHERE, а фильтры по агрегатам — в HAVING.
- Выбирайте в SELECT только ключ, чтобы передать его в подзапрос IN или соединение.
Часто задаваемые вопросы
Урок «Подсчёт и фильтрация групп» бесплатный?
Да — полный текст урока «Подсчёт и фильтрация групп» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Interview Prep, подпишись на CoddyKit PRO. Курс SQL Interview Prep содержит 4 уроков всего.
Чему я научусь в уроке «Подсчёт и фильтрация групп»?
Находите группы, достигающие порога: классический вопрос о клиентах с более чем N заказами. Ты практикуешь SQL Interview Prep с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Interview Prep?
Предыдущий опыт не требуется. SQL Interview Prep на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Подсчёт и фильтрация групп»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Interview Prep?
Да. Каждый урок SQL Interview Prep включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Правило GROUP BY для столбцов SELECT
- HAVING и WHERE
- Группировка по нескольким столбцам и выражениям
- Подсчёт и фильтрация групп