Как посчитать New Users в SQL
user_id и дата signup_at из таблицы пользователей. Какой запрос лучше соответствует задаче и не тянет лишние поля?Содержание:
Зачем New Users
Маркетинг отчитывается: «150K новых пользователей в апреле». Аналитик копает: 30% этого — повторные регистрации (юзер забыл пароль), 20% — боты, 10% — реальные новые на конкретном устройстве (юзер уже был). Реальные new users — 60K.
Что такое New User
New User — пользователь, первая активность которого попадает в исследуемый период.
New = MIN(activity) ∈ periodБазовый расчёт
Данные: users(user_id, signup_date) или events(user_id, event_date).
SELECT
DATE_TRUNC('month', signup_date) AS month,
COUNT(DISTINCT user_id) AS new_users
FROM users
WHERE signup_date >= '2026-01-01'
GROUP BY 1
ORDER BY 1;Если только events:
WITH first_event AS (
SELECT user_id, MIN(event_date) AS first_date
FROM events
GROUP BY user_id
)
SELECT
DATE_TRUNC('month', first_date) AS month,
COUNT(*) AS new_users
FROM first_event
WHERE first_date >= '2026-01-01'
GROUP BY 1
ORDER BY 1;New Users по каналам
SELECT
DATE_TRUNC('month', signup_date) AS month,
acquisition_channel,
COUNT(DISTINCT user_id) AS new_users
FROM users
WHERE signup_date >= '2026-01-01'
GROUP BY 1, 2
ORDER BY 1, new_users DESC;Cross-device дедупликация
Юзер заходит с телефона (device_id A), потом с ПК (device_id B). Без объединения профилей — два user_id, два «новых».
-- Допустим, есть user_links(device_id, user_id) с unified user_id
WITH unified AS (
SELECT
ul.user_id AS unified_user_id,
MIN(e.event_date) AS first_event
FROM events e
JOIN user_links ul ON ul.device_id = e.device_id
GROUP BY ul.user_id
)
SELECT
DATE_TRUNC('month', first_event) AS month,
COUNT(*) AS new_users_unified
FROM unified
WHERE first_event >= '2026-01-01'
GROUP BY 1
ORDER BY 1;Частые ошибки
Ошибка 1. Считать новых по device_id. Кросс-девайс-юзеры дублируются. Используйте user_id (после входа в аккаунт), если он есть.
Ошибка 2. Включать ботов.
Без is_bot = false число новых пользователей завышено.
Ошибка 3. Граница периода. Если юзер пришёл в 23:59 31 марта, signup_date в UTC может оказаться уже 1 апреля. Зафиксируйте таймзону.
Ошибка 4. Повторные регистрации. Юзер забыл пароль и зарегистрировался заново с другой почтой. Объединяйте по отпечатку устройства (device fingerprint).
Ошибка 5. Соотношение новых и вернувшихся. Только новые пользователи — не вся картина. Сравнивайте новых и вернувшихся за один и тот же период.
Связанные темы
- Как посчитать DAU в SQL
- Как посчитать MAU в SQL
- Как посчитать retention в SQL
- Как посчитать reactivation в SQL
FAQ
Cross-device или per-device?
Cross-device-подсчёт через единый user_id точнее: один человек с телефона и с ПК считается как один. Подсчёт по устройствам (per-device) проще в реализации, но завышает число новых. Если есть авторизация, берите cross-device.
Как фильтровать ботов?
Смотрите на User-Agent, географические аномалии и поведение: мгновенный отскок, экзотическое устройство. Но надёжнее подключить готовые антибот-системы вроде reCAPTCHA или Akamai, чем изобретать эвристики самому.
New users падают — что делать?
Разложите падение по каналам привлечения и найдите тот, что просел сильнее всего. Чаще всего проблема локализуется в одном-двух каналах, а не размазана ровным слоем по всем.
New vs Returning?
Новый — тот, чья первая активность попала в исследуемый период. Вернувшийся — тот, кто был активен раньше и снова появился сейчас. Вместе они дают всех активных: активные = новые + вернувшиеся.
Boundary date — куда её относить?
Регистрация 31 марта в 23:50 UTC — это уже 1 апреля 02:50 по МСК. От выбранной таймзоны зависит, в какой месяц попадёт пользователь, поэтому зафиксируйте её раз и навсегда, чтобы цифры сходились между отчётами.