Data Analyst Professional · Модуль 4 · Урок 13 із 51
GROUP BY та агрегатні функції: правильний grain результату
Агрегація стискає багато source rows до одного рядка на кожну групу. Професійний запит явно визначає grouping grain, розрізняє COUNT(*), COUNT(field) і COUNT(DISTINCT key), а rates рахує як ratio of sums.
GROUP BY змінює grain
SELECT
country_code,
DATE_TRUNC('month', order_ts) AS order_month,
COUNT(*) AS order_row_count,
COUNT(DISTINCT order_id) AS unique_orders,
SUM(net_amount) AS net_revenue
FROM analytics.orders
WHERE status = 'completed'
GROUP BY country_code, DATE_TRUNC('month', order_ts);Результат має grain country × month. Кожна неагрегована колонка SELECT повинна бути частиною GROUP BY або функціонально визначатися нею відповідно до правил СУБД.
COUNT має три різні сенси
| Вираз | Що рахує | NULL | Типове застосування |
|---|---|---|---|
| COUNT(*) | рядки групи | включає рядок | row count на source grain |
| COUNT(email) | non-NULL email | пропускає NULL | заповнені значення |
| COUNT(DISTINCT customer_id) | унікальні non-NULL customer IDs | NULL не рахується | unique customers |
Називайте одиницю
count — слабкий alias. Використовуйте order_row_count, customers_with_email або unique_customers.
NULL в SUM і AVG
Більшість агрегатних функцій ігнорує NULL. Якщо всі значення групи NULL, SUM може повернути NULL, а не zero. COALESCE(SUM(amount),0) допустимий лише коли бізнес справді трактує відсутність фактів як нульову суму.
WHERE фільтрує rows, HAVING — groups
SELECT customer_id, SUM(net_amount) AS revenue
FROM analytics.orders
WHERE status = 'completed' -- до aggregation
GROUP BY customer_id
HAVING SUM(net_amount) >= 10000; -- після aggregationУ WHERE не можна посилатися на результат агрегату того самого рівня. HAVING відбирає вже сформовані groups; не переносіть туди звичайний row filter без причини.
Rate: ratio of sums, не average of row rates
SELECT
channel,
SUM(conversions) AS conversions,
SUM(sessions) AS sessions,
SUM(conversions)::numeric / NULLIF(SUM(sessions), 0) AS conversion_rate
FROM analytics.daily_channel
GROUP BY channel;Середнє денних rates надає малому й великому дню однакову вагу. Ratio of sums використовує фактичний denominator. NULLIF(...,0) явно захищає division by zero.
Практика: metric reconciliation
- Запишіть source grain і output grouping grain.
- Порівняйте COUNT(*), COUNT(key), COUNT(DISTINCT key).
- Порахуйте NULL у measure і поясніть denominator AVG.
- Застосуйте WHERE до row scope і HAVING до aggregate threshold.
- Звірте sum groups із control total без grouping.
Офіційні довідки
Готовність до тесту
Ви називаєте grain group result, розрізняєте види COUNT, знаєте NULL semantics, використовуєте HAVING за призначенням і рахуєте weighted rate через ratio of sums.
Закріпіть матеріал уроку
Три сценарні питання. Для зарахування уроку потрібно дати щонайменше дві правильні відповіді.