Среднее время доставки по городам (с учётом NULL)
// Условие
Для каждого города пользователя посчитайте: среднее время доставки в днях (avg_delivery, округлить до 1), долю заказов без данных о доставке (null_rate — процент NULL в delivery_days среди завершённых заказов, округлить до 1). Только города с ≥ 100 завершёнными заказами. Отсортируйте по avg_delivery.
// Таблицы
user_id | INT |
registration_date | DATE |
acquisition_channel | VARCHAR(20) |
platform | VARCHAR(10) |
city | VARCHAR(50) |
is_premium | BOOLEAN |
order_id | INT |
user_id | INT |
order_date | TIMESTAMP |
amount | NUMERIC(10,2) |
status | VARCHAR(20) |
delivery_days | INT |
promo_code | VARCHAR(20) |
// Что тренирует
// Решение
Подсказка
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 мышление.