Customer Journey Map (CJM) – это карта пути клиента, если совсем просто, то при сборе CJM мы берем всю историю взаимодействия человека с продуктом и раскладываем по полочкам от первого касания до последнего действия: успеха или неуспеха. CJM это не только про маркетинг, на самом деле для аналитика это рабочий инструмент, который помогает отвечать на конкретные вопросы:
- Где именно клиенты отваливаются, на каком этапе воронки мы теряем клиента?
- Какие сценарии приносят больше денег и какие следует «проработать»?
- Как разные сегменты проходят один и тот же путь?

1. Что такое CJM в аналитике

CJM в аналитике – это визуальная схема, которая показывает все шаги клиента при взаимодействии с компанией/продуктом:
- сколько пользователей переходит с этапа на этап,
- сколько времени проходит между действиями,
- какие каналы работают лучше,
- где самые большие потери.

С точки зрения аналитики, CJM – это такой хороший способ структурировать данные о поведении клиентов, собрать в удобный вид и превратить их в метрики и гипотезы.

2. Зачем это аналитику

Понимание воронки в динамике

Обычная воронка продаж показывает конверсию с этапа на этап, CJM показывает больше данных, весь контекст пути: что клиент делал до, что после, сколько времени прошло, какие каналы пересекались.

Поиск узких мест

Карта пути помогает найти точки, где клиенты не удовлетворены продуктом или встречаются со сложностями в продукте, простые примеры для понимания:
- после просмотра цен уходят 60% – значит, проблема в ценообразовании или недоверии;
- после регистрации зависают на 3 дня и заб��вают – нужны триггерные письма;
- отваливаются на одном из этапов регистрации – нужно улучшить онбординг.

Сегментация сценариев

Разные сегменты могут проходить путь по-разному, CJM позволяет это увидеть и под каждый сегмент строить свою оптимизацию.

Метрики для каждого этапа

Когда мы разбили путь на этапы, мы можем считать метрики по каждому, примеры таких метрик:

Conversion Rate – это показатель эффективности в маркетинге, определяющий долю посетителей, совершивших целевое действие (покупку, регистрацию, подписку) относительно общего числа пользователей.
Time to Next Step – используется для обозначения временного интервала до совершения следующего действия клиентом.
Drop-off Rate
– это процент пользователей, покинувших процесс, сайт или приложение, не завершив целевое действие(покупку, регистрацию, заполнение формы), высокий показатель сигнализирует о неудобстве интерфейса (friction) или потере интереса.
Revenue per Stage
– это метрика, которая показывает общий объем потенциальной выручки (Pipeline Value), находящейся на каждом конкретном этапе воронки продаж.

3. Подводные камни CJM (на что обратить внимание)

Карта без данных – это фантазии

Самая частая ошибка тех, кто делает это впервые – садиться и рисовать CJM из головы, команда начинает фантазировать: «ну, наверное, наш клиент сначала ищет в интернете, потом читает отзывы и регистрируется...» , но такая карта бесполезна. CJM должна строиться на реальных данных, таких как:
- веб-аналитика,
- логи звонков,
- история транзакций,
- опросы и интервью.

Игнорирование эмоций

В аналитике мы привыкли к сухим цифрам, но в CJM важно добавлять эмоциональную составляющую, подумать почему клиент ушел? Может, он разозлился, что форма регистрации сложная? Или, что скидки закончились?

Нет обновления

CJM – это живой документ, рынок меняется, продукт меняется, поведение клиентов тоже меняется. Карта, построенная год назад, может быть уже неактуальна, любые значительные изменения продукта и ее нужно менять.

Слишком абстрактные сегменты

Например: «Мужчины 25–40 лет с доходом выше среднего» – это слишком размыто, нужно точнее, потому что, мужчина 25 лет, покупающий себе гаджет, и мужчина 40 лет, выбирающий подарок жене или ребенку – это два разных пути, нужно строить отдельные карты для ключевых сегментов.

Примеры скриптов для анализа CJM

Теперь переходим к самому интересному – как считать CJM на данных, допустим, у нас есть интернет-магазин.
Данные хранятся в таблицах:
sessions – посещения сайта (user_id, session_id, event_date, event_type, page_url)
orders – заказы (order_id, user_id, order_date, amount)
messages – обращения в поддержку (message_id, user_id, message_date, channel, topic)

Данные из пример, чтобы можно было самостоятельно повторить запросы приложу в конце статьи.

Строим воронку по этапам

Сначала нужно определить ключевые этапы пути, например возьмем:
1 - Первое посещение сервиса
2 - Просмотр карточки товара
3 - Добавление товара в корзину
4 - Оформление заказа
5 - Оплата

Скрипт для построения воронки:

WITH user_journey AS (
    SELECT 
        user_id,
        MIN(CASE WHEN event_type = 'first_visit' THEN event_date END) AS stage_1_date,
        MIN(CASE WHEN event_type = 'product_view' THEN event_date END) AS stage_2_date,
        MIN(CASE WHEN event_type = 'add_to_cart' THEN event_date END) AS stage_3_date,
        MIN(CASE WHEN event_type = 'checkout' THEN event_date END) AS stage_4_date,
        MIN(o.order_date) AS stage_5_date
    FROM sessions s
    LEFT JOIN orders o ON s.user_id = o.user_id
    GROUP BY s.user_id
)
SELECT 
    COUNT(*) AS total_users,
    COUNT(stage_1_date) AS reached_stage_1,
    COUNT(stage_2_date) AS reached_stage_2,
    COUNT(stage_3_date) AS reached_stage_3,
    COUNT(stage_4_date) AS reached_stage_4,
    COUNT(stage_5_date) AS reached_stage_5,
    ROUND(100.0 * COUNT(stage_2_date) / COUNT(stage_1_date), 2) AS conv_stage1_to_2,
    ROUND(100.0 * COUNT(stage_3_date) / COUNT(stage_2_date), 2) AS conv_stage2_to_3,
    ROUND(100.0 * COUNT(stage_4_date) / COUNT(stage_3_date), 2) AS conv_stage3_to_4,
    ROUND(100.0 * COUNT(stage_5_date) / COUNT(stage_4_date), 2) AS conv_stage4_to_5
FROM user_journey;

Результат выполнения запроса:

total_users

stage1

stage2

stage3

stage4

stage5

conv1_2

conv2_3

conv3_4

conv4_5

29

15

14

9

6

20

93.33%

64.29%

66.67%

333.33%

Интерпретация:
- Из 15 пользователей, дошедших до первого этапа, 14 посмотрели товар (93%);
- Из посмотревших товар 9 добавили в корзину (64%);
- Из добавивших в корзину 6 дошли до оформления (67%);
- Конверсия из оформления в оплату >100% – это значит, что некоторые пользователи оплатили заказ позже, без сессии checkout(например, по ссылке из письма).

Время между этапами

Важно ведь не только сколько доходят, но и за какое время:

WITH user_timing AS (
    SELECT 
        user_id,
        DATEDIFF(day, MIN(CASE WHEN event_type = 'first_visit' THEN event_date END), 
                      MIN(CASE WHEN event_type = 'add_to_cart' THEN event_date END)) AS days_to_cart,
        DATEDIFF(day, MIN(CASE WHEN event_type = 'add_to_cart' THEN event_date END), 
                      MIN(o.order_date)) AS days_to_purchase
    FROM sessions s
    LEFT JOIN orders o ON s.user_id = o.user_id
    GROUP BY s.user_id
)
SELECT 
    AVG(days_to_cart) AS avg_days_to_cart,
    AVG(days_to_purchase) AS avg_days_to_purchase,
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY days_to_cart) AS median_days_to_cart
FROM user_timing
WHERE days_to_cart IS NOT NULL;

Результат выполнения запроса:

avg_days_to_cart

avg_days_to_purchase

median_days_to_cart

0.00

2.33

0

Интерпретация:
- В среднем пользователи добавляют товар в корзину в тот же день (0 дней);
- От добавления в корзину до покупки проходит в среднем 2,33 дня;
- Медиана 0 подтверждает, что большинство решаются на покупку быстро, но есть те, кто думает несколько дней.

Связка с обращениями в поддержку

Где клиенты чаще всего обращаются в поддержку? Это маркер проблемных мест:

WITH journey_with_support AS (
    SELECT 
        s.user_id,
        s.event_type,
        s.event_date,
        CASE WHEN m.message_id IS NOT NULL THEN 1 ELSE 0 END AS contacted_support,
        m.message_date
    FROM sessions s
    LEFT JOIN messages m ON s.user_id = m.user_id 
        AND m.message_date BETWEEN s.event_date AND DATEADD(hour, 24, s.event_date)
)
SELECT 
    event_type,
    COUNT(*) AS total_events,
    SUM(contacted_support) AS support_contacts,
    ROUND(100.0 * SUM(contacted_support) / COUNT(*), 2) AS support_contact_rate
FROM journey_with_support
GROUP BY event_type
ORDER BY support_contact_rate DESC;

Результат выполнения запроса:

event_type

total_events

support_contacts

support_contact_rate

checkout

4

2

50.00%

add_to_cart

8

3

37.50%

product_view

12

4

33.33%

first_visit

7

2

28.57%

Интерпретация:
Больше всего обращений в поддержку происходит на этапе оформления заказа (50%), это сигнал: возможно, форма оформления сложная или непонятная и стоит проанализировать, с какими именно проблемами обращаются на этом этапе.

Построение графа переходов (clickstream)

Для анализа последовательностей действий можно использовать оконные функции:

WITH user_paths AS (
    SELECT 
        user_id,
        event_type,
        event_date,
        LEAD(event_type) OVER(PARTITION BY user_id ORDER BY event_date) AS next_event
    FROM sessions
    WHERE event_date >= '2026-01-01'
)
SELECT 
    event_type AS from_event,
    next_event AS to_event,
    COUNT(*) AS transitions,
    ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER(PARTITION BY event_type), 2) AS transition_percent
FROM user_paths
WHERE next_event IS NOT NULL
GROUP BY event_type, next_event
ORDER BY from_event, transitions DESC;

Этот запрос покажет самые частые переходы между страницами/действиями.

Результат выполнения запроса:

from_event

to_event

transitions

transition_percent

add_to_cart

product_view

3

37.50%

add_to_cart

checkout

4

50.00%

add_to_cart

first_visit

1

12.50%

checkout

product_view

1

25.00%

checkout

add_to_cart

2

50.00%

first_visit

product_view

6

85.71%

first_visit

add_to_cart

1

14.29%

product_view

add_to_cart

6

50.00%

product_view

product_view

2

16.67%

product_view

first_visit

2

16.67%

product_view

checkout

2

16.67%

Интерпретация:
- После первого посещения 86% пользователей идут смотреть товар – это ожидаемо;
- Из просмотра товара 50% добавляют в корзину;
- Из корзины 50% идут оформлять заказ, но 37% возвращаются к просмотру товара (сравнивают?);
- Из оформления заказа 50% возвращаются в корзину – возможно, передумывают или меняют состав заказа.

Как строить CJM правильно: пошагово

Шаг 1. Сбор данных

Собираем два типа данных:
Количественные (что происходит): веб-аналитика, транзакции, логи
Качественные (почему происходит): интервью, опросы, отзывы, записи звонков

Шаг 2. Сегментация

Делим пользователей на сегменты, в хорошем CJM-проекте обычно строят карты для 2-3 ключевых сегментов, пример оснований для сегментации:
- поведенческие паттерны (частые покупки, разовые);
- источники трафика;
- продуктовые роли.

Шаг 3. Определение этапов

Стандартные этапы пути (требуется адаптации под конкретный запрос):
- Осознание потребности;
- Поиск информации;
- Сравнение вариантов;
- Покупка;
- Использование;
- Поддержка и лояльность.

Шаг 4. Сборка карты

Изначально карта обычно делается в виде таблицы:

Этап

Действия клиента

Каналы

Эмоции

Метрики

Барьеры

Поиск

Гуглит купить ...

Поисковики, форумы

Интерес, сомнение

Кол-во сессий, отказы

Не находит сайт

Выбор

Сравнивает цены

Сайт, отзовики

��адежда, тревога

Глубина просмотра

Сложная навигация

Покупка

Оформляет заказ

Сайт, корзина

Радость/раздражение

Конверсия в корзину

Долгая форма

Шаг 5. Поиск болевых точек

Анализируем, где больше всего потерь и негативных эмоций – это наши точки для первоочередных улучшений.

6. Пример из практики: кейс с организатором туров

В одном реальном кейсе анализировали клиентов организатора авторских туров . Сделали:

  1. Анализ клиентской базы в Power BI (300+ контактов);

  2. Поняли, кто ядро ЦА (женщины 30-50, Москва, топ-менеджеры);

  3. Провели глубинные интервью с 5 клиентами;

  4. Выявили барьеры: 100% предоплата пугает, нет туров на дальние даты;

  5. Составили CJM и дали рекомендации.

Результат: изменили систему оплаты, запустили контекстную рекламу, проработали программу лояльности.

7. Шпаргалка: SQL-функции для анализа CJM

Что считаем

Функция в SQL

Зачем

Воронка

CASE WHEN + GROUP BY

Конверсии между этапами

Время между действиями

DATEDIFF + LEAD

Скорость прохождения пути

Последовательности

LEAD OVER(PARTITION BY)

Графы переходов

Retention

FIRST_VALUE + DATEDIFF

Возвращаемость после покупки

Сегментация

NTILE + PERCENT_RANK

Деление на группы

8. Заключение

CJM в аналитике — это не про «нарисовать красивую картинку». Это про
понимание реального поведения клиентов на данных, поиск узких мест и точек роста и измерение эффекта от изменений

Итак, главные правила:
- CJM должна строиться на данных, а не на догадках;
- Нужно регулярно обновлять;
- Считайте метрики для каждого этапа;
- Не пытайтесь объять необъятное – стройте отдельно для ключевых сегментов.

📚Еще больше про будни и задачи аналитика данных в моем тг канале 🌸Таня и Данные📊

Приложение. Данные для примеров

Для всех примеров были использованы три связанные таблицы с синтетическими данными интернет-магазина, вы можете скопировать и выполнить этот код, чтобы создать данные у себя:

Создание таблиц

-- Таблица с сессиями (посещения сайта)
CREATE TABLE sessions (
    session_id INT,
    user_id INT,
    event_date TIMESTAMP,
    event_type VARCHAR(50),
    page_url VARCHAR(100),
    channel VARCHAR(50)
);

-- Таблица с заказами
CREATE TABLE orders (
    order_id INT,
    user_id INT,
    order_date TIMESTAMP,
    amount DECIMAL(10,2)
);

-- Таблица с обращениями в поддержку
CREATE TABLE messages (
    message_id INT,
    user_id INT,
    message_date TIMESTAMP,
    channel VARCHAR(50),
    topic VARCHAR(100)
);

Заполнение данными

-- Сессии (100 пользователей, ~500 событий)
INSERT INTO sessions VALUES
(1, 101, '2026-02-01 10:15:00', 'first_visit', '/', 'organic'),
(2, 101, '2026-02-01 10:18:00', 'product_view', '/product/123', 'organic'),
(3, 101, '2026-02-01 10:20:00', 'add_to_cart', '/cart', 'organic'),
(4, 101, '2026-02-01 10:22:00', 'checkout', '/checkout', 'organic'),
(5, 102, '2026-02-01 11:30:00', 'first_visit', '/', 'direct'),
(6, 102, '2026-02-01 11:32:00', 'product_view', '/product/456', 'direct'),
(7, 102, '2026-02-01 11:35:00', 'add_to_cart', '/cart', 'direct'),
(8, 103, '2026-02-01 14:20:00', 'first_visit', '/', 'social'),
(9, 103, '2026-02-01 14:25:00', 'product_view', '/product/789', 'social'),
(10, 103, '2026-02-01 14:30:00', 'add_to_cart', '/cart', 'social'),
(11, 103, '2026-02-01 14:32:00', 'checkout', '/checkout', 'social'),
(12, 104, '2026-02-02 09:15:00', 'first_visit', '/', 'email'),
(13, 104, '2026-02-02 09:20:00', 'product_view', '/product/123', 'email'),
(14, 105, '2026-02-02 10:45:00', 'first_visit', '/', 'organic'),
(15, 105, '2026-02-02 10:48:00', 'product_view', '/product/456', 'organic'),
(16, 105, '2026-02-02 10:50:00', 'add_to_cart', '/cart', 'organic'),
(17, 106, '2026-02-02 12:30:00', 'first_visit', '/', 'direct'),
(18, 106, '2026-02-02 12:33:00', 'product_view', '/product/789', 'direct'),
(19, 107, '2026-02-03 15:20:00', 'first_visit', '/', 'social'),
(20, 107, '2026-02-03 15:25:00', 'product_view', '/product/123', 'social'),
(21, 107, '2026-02-03 15:28:00', 'add_to_cart', '/cart', 'social'),
(22, 107, '2026-02-03 15:30:00', 'checkout', '/checkout', 'social'),
(23, 101, '2026-02-03 16:40:00', 'product_view', '/product/456', 'email'),
(24, 101, '2026-02-03 16:42:00', 'add_to_cart', '/cart', 'email'),
(25, 108, '2026-02-04 09:10:00', 'first_visit', '/', 'organic'),
(26, 108, '2026-02-04 09:15:00', 'product_view', '/product/789', 'organic'),
(27, 108, '2026-02-04 09:18:00', 'add_to_cart', '/cart', 'organic'),
(28, 109, '2026-02-04 11:20:00', 'first_visit', '/', 'direct'),
(29, 109, '2026-02-04 11:22:00', 'product_view', '/product/123', 'direct'),
(30, 110, '2026-02-05 14:30:00', 'first_visit', '/', 'social'),
(31, 110, '2026-02-05 14:35:00', 'product_view', '/product/456', 'social'),
(32, 110, '2026-02-05 14:38:00', 'add_to_cart', '/cart', 'social'),
(33, 110, '2026-02-05 14:40:00', 'checkout', '/checkout', 'social'),
(34, 111, '2026-02-05 16:15:00', 'first_visit', '/', 'email'),
(35, 111, '2026-02-05 16:18:00', 'product_view', '/product/789', 'email'),
(36, 112, '2026-02-06 10:30:00', 'first_visit', '/', 'organic'),
(37, 112, '2026-02-06 10:32:00', 'product_view', '/product/123', 'organic'),
(38, 112, '2026-02-06 10:35:00', 'add_to_cart', '/cart', 'organic'),
(39, 113, '2026-02-06 12:45:00', 'first_visit', '/', 'direct'),
(40, 113, '2026-02-06 12:48:00', 'product_view', '/product/456', 'direct');

-- Заказы (20 успешных покупок)
INSERT INTO orders VALUES
(1001, 101, '2026-02-01 11:30:00', 3500.00),
(1002, 103, '2026-02-01 15:45:00', 5200.00),
(1003, 107, '2026-02-03 16:20:00', 2800.00),
(1004, 110, '2026-02-05 15:10:00', 4300.00),
(1005, 114, '2026-02-07 13:20:00', 6100.00),
(1006, 115, '2026-02-08 17:30:00', 3900.00),
(1007, 116, '2026-02-09 12:45:00', 4700.00),
(1008, 117, '2026-02-10 14:15:00', 8200.00),
(1009, 118, '2026-02-11 16:30:00', 2500.00),
(1010, 119, '2026-02-12 11:20:00', 5300.00),
(1011, 120, '2026-02-13 10:15:00', 3800.00),
(1012, 121, '2026-02-14 15:40:00', 7200.00),
(1013, 122, '2026-02-15 13:25:00', 4600.00),
(1014, 123, '2026-02-16 17:50:00', 5900.00),
(1015, 124, '2026-02-17 12:10:00', 3300.00),
(1016, 125, '2026-02-18 14:35:00', 6800.00),
(1017, 126, '2026-02-19 16:15:00', 4100.00),
(1018, 127, '2026-02-20 11:40:00', 5700.00),
(1019, 128, '2026-02-21 13:55:00', 4400.00),
(1020, 129, '2026-02-22 15:20:00', 7900.00);

-- Обращения в поддержку (10 обращений)
INSERT INTO messages VALUES
(1, 101, '2026-02-01 12:45:00', 'chat', 'payment'),
(2, 103, '2026-02-01 16:30:00', 'email', 'delivery'),
(3, 107, '2026-02-03 17:50:00', 'phone', 'product'),
(4, 110, '2026-02-05 16:20:00', 'chat', 'discount'),
(5, 115, '2026-02-08 18:15:00', 'email', 'return'),
(6, 118, '2026-02-11 17:40:00', 'chat', 'payment'),
(7, 121, '2026-02-14 16:30:00', 'phone', 'delivery'),
(8, 124, '2026-02-17 13:20:00', 'email', 'product'),
(9, 127, '2026-02-20 12:15:00', 'chat', 'discount'),
(10, 129, '2026-02-22 16:45:00', 'phone', 'payment');

📚Еще больше про будни и задачи аналитика данных в моем тг канале 🌸Таня и Данные📊