SQLАгрегация и GROUP BYEasyБесплатно

Сравнение Premium и обычных пользователей

// Условие

Сравните Premium и обычных пользователей: для каждой группы (is_premium) посчитайте количество пользователей (user_count), общее количество завершённых заказов (order_count) и среднее количество заказов на пользователя (avg_orders_per_user, округлить до 2 знаков). Отсортируйте по is_premium по убыванию (Premium первым).

// Таблицы

sandbox.users
user_idINT
registration_dateDATE
acquisition_channelVARCHAR(20)
platformVARCHAR(10)
cityVARCHAR(50)
is_premiumBOOLEAN
sandbox.orders
order_idINT
user_idINT
order_dateTIMESTAMP
amountNUMERIC(10,2)
statusVARCHAR(20)
delivery_daysINT
promo_codeVARCHAR(20)

// Что тренирует

LEFT JOINGROUP BYCOUNT DISTINCTЦелочисленное деление
▶ Решить в SQL-песочнице

// Решение

Подсказка

LEFT JOIN users → orders (чтобы не потерять пользователей без заказов). COUNT(DISTINCT u.user_id) для user_count, COUNT(o.order_id) для order_count.

Сначала попробуй сам → Показать решение
SELECT
  u.is_premium,
  COUNT(DISTINCT u.user_id) AS user_count,
  COUNT(o.order_id) AS order_count,
  ROUND(COUNT(o.order_id)::numeric / COUNT(DISTINCT u.user_id), 2) AS avg_orders_per_user
FROM sandbox.users u
LEFT JOIN sandbox.orders o
  ON u.user_id = o.user_id
  AND o.status = 'completed'
GROUP BY u.is_premium
ORDER BY u.is_premium DESC;

Три ключевых момента: (1) LEFT JOIN — чтобы включить пользователей без заказов; (2) условие status = 'completed' стоит в ON, а не в WHERE — иначе LEFT JOIN превратится в INNER JOIN и потеряет пользователей без заказов; (3) ::numeric перед делением — иначе PostgreSQL сделает целочисленное деление. Это ловушка, в которую попадает ~60% кандидатов.

// Похожие задачи

// Разобраться в теме

→ GROUP BY и HAVING в SQL