SQLДаты и NULLMediumБесплатно

Среднее время доставки по городам (с учётом NULL)

// Условие

Для каждого города пользователя посчитайте: среднее время доставки в днях (avg_delivery, округлить до 1), долю заказов без данных о доставке (null_rate — процент NULL в delivery_days среди завершённых заказов, округлить до 1). Только города с ≥ 100 завершёнными заказами. Отсортируйте по avg_delivery.

// Таблицы

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)

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

NULLCOALESCECASE WHENAVG
▶ Решить в SQL-песочнице

// Решение

Подсказка

AVG() автоматически игнорирует NULL. Для null_rate: COUNT(*) - COUNT(delivery_days) = количество NULL. Или SUM(CASE WHEN delivery_days IS NULL THEN 1 ELSE 0 END).

Сначала попробуй сам → Показать решение
SELECT
  u.city,
  ROUND(AVG(o.delivery_days), 1) AS avg_delivery,
  ROUND(
    100.0 * SUM(CASE WHEN o.delivery_days IS NULL THEN 1 ELSE 0 END) / COUNT(*),
    1
  ) AS null_rate
FROM sandbox.users u
JOIN sandbox.orders o ON u.user_id = o.user_id
WHERE o.status = 'completed'
GROUP BY u.city
HAVING COUNT(*) >= 100
ORDER BY avg_delivery;

Ключевые моменты: (1) AVG() в PostgreSQL пропускает NULL — это значит avg_delivery считается только по заполненным значениям; (2) для подсчёта NULL используем CASE WHEN ... IS NULL — это надёжный способ; (3) HAVING COUNT(*) >= 100 отсекает маленькие города. На собесе могут спросить: «а что, если NULL не случайные, а коррелируют с долгой доставкой?» — это вопрос на data quality мышление.

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