Как посчитать Exit Rate в SQL

Проверь себя · 1/3разбор после ответа
Нужно получить 10 последних событий конкретного пользователя (user_id = 42) из таблицы events(user_id, event_time, event_name). Какой запрос корректнее всего решает задачу?

Зачем Exit Rate

Exit Rate = % сессий, для которых страница X оказалась последней просмотренной. Метрику используют для оптимизации воронки. Страницы с высоким exit rate на важных шагах — это точки утечки, где пользователи уходят.

Формула

Exit Rate (page) = sessions_ended_on_page / total_sessions_visited_page × 100%

Базовый расчёт

WITH page_visits AS (
    SELECT
        session_id,
        page_url,
        event_time,
        ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY event_time DESC) AS rn_from_end
    FROM events
    WHERE event_name = 'page_view'
      AND event_time >= CURRENT_DATE - INTERVAL '7 days'
)
SELECT
    page_url,
    COUNT(*) AS total_visits,
    COUNT(*) FILTER (WHERE rn_from_end = 1) AS exits,
    COUNT(*) FILTER (WHERE rn_from_end = 1)::NUMERIC * 100 / COUNT(*) AS exit_rate_pct
FROM page_visits
GROUP BY page_url
HAVING COUNT(*) >= 50
ORDER BY exits DESC
LIMIT 50;

Exit Rate vs Bounce Rate

Метрика Определение
Bounce Rate % сессий ровно с одним просмотром страницы (сессия из одной страницы)
Exit Rate % сессий, закончившихся на странице X (любая сессия)

Bounce считается только для входной страницы. Exit — для любой страницы в последовательности.

-- Bounce: session has 1 PV total
WITH session_pv_count AS (
    SELECT session_id, COUNT(*) AS pvs
    FROM events
    WHERE event_name = 'page_view'
    GROUP BY session_id
)
SELECT
    COUNT(*) FILTER (WHERE pvs = 1)::NUMERIC * 100 / COUNT(*) AS bounce_rate_pct
FROM session_pv_count;

-- Exit: last page in any session
-- (already shown above)
Закрепи формулу exit rate в Карьернике
Запомнить надолго — 5 коротких сессий с задачами на эту тему. Бесплатно
Тренировать exit rate в Telegram

Топ страниц по exit rate

Страницы с аномально высоким exit rate:

WITH stats AS (
    SELECT
        page_url,
        COUNT(*) AS total_visits,
        COUNT(*) FILTER (WHERE rn_from_end = 1)::NUMERIC * 100 / COUNT(*) AS exit_rate
    FROM (
        SELECT
            page_url,
            ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY event_time DESC) AS rn_from_end
        FROM events
        WHERE event_name = 'page_view'
          AND event_time >= CURRENT_DATE - INTERVAL '30 days'
    ) e
    GROUP BY page_url
    HAVING COUNT(*) >= 100
),
avg_stats AS (
    SELECT AVG(exit_rate) AS avg_exit
    FROM stats
)
SELECT
    s.page_url,
    s.total_visits,
    s.exit_rate,
    a.avg_exit,
    s.exit_rate - a.avg_exit AS diff_from_avg
FROM stats s, avg_stats a
WHERE s.exit_rate > a.avg_exit * 1.5
ORDER BY s.exit_rate DESC;

По шагам воронки

WITH funnel_pages AS (
    SELECT
        session_id,
        page_url,
        ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY event_time) AS step,
        ROW_NUMBER() OVER (PARTITION BY session_id ORDER BY event_time DESC) AS rn_from_end
    FROM events
    WHERE event_name = 'page_view'
      AND page_url IN ('/landing', '/signup', '/checkout', '/confirmation')
)
SELECT
    page_url,
    COUNT(*) AS visits,
    COUNT(*) FILTER (WHERE rn_from_end = 1)::NUMERIC * 100 / COUNT(*) AS exit_rate
FROM funnel_pages
GROUP BY page_url
ORDER BY visits DESC;

Частые ошибки

Ошибка 1. Путать с bounce. Bounce — это сессии из одной страницы. Exit — последняя страница в сессии из нескольких страниц. Это разные метрики, их нельзя смешивать.

Ошибка 2. Не фильтровать малый объём. Страница с 5 визитами и 80% выходов — это шум, а не сигнал. Ставьте минимальный порог по размеру выборки.

Ошибка 3. Целевые страницы. На страницах «спасибо» и подтверждения высокий exit — это норма: пользователь дошёл до цели и закрыл вкладку. Достижение цели и есть выход.

Ошибка 4. Тайм-аут сессии как выход. Пользователь просто отошёл — и это засчиталось как выход. Но он мог отвлечься и вернуться. Заранее определите, что именно считать выходом.

Ошибка 5. Несколько устройств. Начал оформление на телефоне, завершил на компьютере — выглядит как выход, но на деле это не он.

Связанные темы

FAQ

Exit vs Bounce?

Bounce — это сессия из одной-единственной страницы: человек зашёл и сразу ушёл. Exit — это последняя страница в любой сессии, даже если до неё было ещё десять просмотров. Поэтому одна и та же страница может давать высокий exit rate и при этом низкий bounce rate.

Высокий exit — это всегда плохо?

На целевых страницах вроде подтверждения заказа — нет, это нормально: пользователь дошёл до цели и закрыл вкладку. А вот высокий выход на промежуточном шаге воронки — тревожный сигнал, именно там теряются деньги.

Как считать выход при переходе между устройствами?

Если user_id прокидывается между устройствами, смотрите на сквозной путь пользователя, а не на отдельные сессии. Если сквозной идентификации нет, придётся считать по каждому устройству отдельно и мириться с завышенным exit rate.

Exit rate всегда 100% где-то?

Каждая сессия обязательно где-то заканчивается, поэтому суммарно число выходов равно числу сессий. Но exit rate по конкретной странице может быть любым — он зависит от того, насколько часто пользователи уходят именно на ней.

Считается ли тайм-аут выходом?

В Google Analytics по умолчанию 30 минут бездействия закрывают сессию, и последняя страница засчитывается как выход. Это стандартное правило, но порог неактивности можно настроить под свой продукт.