SQL для аналитики в геймдеве

Проверь себя · 1/3разбор после ответа
Вы хотите сравнить текущую метрику с метрикой следующего периода во временном ряду. Какая оконная функция возвращает «следующее» значение относительно текущей строки по заданному порядку сортировки?

Зачем это знать

У игровой индустрии своя специфика: огромные объёмы событий, длинные воронки, сильная монетизация у малой доли игроков, чувствительность к ранним метрикам удержания. В статье — обзор ключевых метрик и типовых SQL-паттернов.

Статья носит общий характер. Конкретные подходы и benchmarks различаются от проекта к проекту и от жанра к жанру. Любые цифры воспринимайте как ориентиры, а не как абсолютную истину.

Ключевые метрики

Аудитория

  • DAU / MAU — активные пользователи
  • Stickiness — DAU / MAU, мера регулярности использования
  • Новые установки и реактивация

Удержание

  • D1 / D7 / D30 retention — классика игровой аналитики. Конкретные значения сильно зависят от жанра.

Монетизация

  • ARPDAU — средний доход на DAU
  • ARPPU — средний доход на платящего игрока
  • Paying rate — доля платящих игроков (обычно невелика)
  • LTV — по когортам

Игровой процесс

  • Session length и sessions per user per day
  • Completion rate уровней
  • Экономика виртуальной валюты
  • Использование items / skins

Типичные SQL-задачи

DAU по дням

SELECT
    DATE(event_time) AS day,
    COUNT(DISTINCT user_id) AS dau
FROM events
WHERE event_time >= CURRENT_DATE - 30
GROUP BY 1
ORDER BY 1;

Retention D7

WITH cohort AS (
    SELECT user_id, DATE(MIN(event_time)) AS signup_date
    FROM events
    GROUP BY user_id
),
d7 AS (
    SELECT c.user_id
    FROM cohort c
    JOIN events e ON e.user_id = c.user_id
    WHERE DATE(e.event_time) = c.signup_date + INTERVAL '7 days'
)
SELECT COUNT(DISTINCT d7.user_id) * 1.0 / COUNT(DISTINCT cohort.user_id) AS d7_retention
FROM cohort
LEFT JOIN d7 USING (user_id);

Сегментация платящих

WITH spend AS (
    SELECT user_id, SUM(amount) AS total_spent
    FROM purchases
    WHERE purchased_at >= CURRENT_DATE - 30
    GROUP BY user_id
)
SELECT
    CASE
        WHEN total_spent >= 10000 THEN 'Top spenders'
        WHEN total_spent >= 1000  THEN 'High spenders'
        WHEN total_spent > 0      THEN 'Paying'
        ELSE 'Non-paying'
    END AS segment,
    COUNT(*) AS players,
    SUM(total_spent) AS revenue
FROM spend
GROUP BY 1;

Прохождение уровней

SELECT
    level_id,
    COUNT(*) AS attempts,
    AVG(CASE WHEN completed THEN 1 ELSE 0 END) AS completion_rate
FROM level_attempts
GROUP BY level_id
ORDER BY completion_rate;

Низкая доля прохождения — кандидат на балансировку.

Экономика валюты

SELECT
    DATE(event_at) AS day,
    SUM(CASE WHEN event_type = 'earn'  THEN amount ELSE 0 END) AS earned,
    SUM(CASE WHEN event_type = 'spend' THEN amount ELSE 0 END) AS spent
FROM currency_events
WHERE event_at >= CURRENT_DATE - 30
GROUP BY 1;

Помогает отследить инфляцию / дефляцию внутриигровой валюты.

Прокачай SQL для собеса
500+ задач по SQL: оконные функции, JOIN, CTE — с разбором каждой
Тренировать SQL в Telegram

На что обратить внимание

  • Скорее всего вы будете работать с колоночными СУБД (ClickHouse, Druid, Pinot) — знание особенностей полезно.
  • Retention и когорты важнее абсолютных цифр.
  • У игровой аналитики часто сильная сезонность и зависимость от релизов.
  • Малая доля «топ-платящих» даёт непропорционально большой вклад в выручку — помните про разрез по сегментам.

Для кого индустрия

Крупные игровые студии с русскоязычным рынком / корнями — Playrix, Wargaming, Gaijin, MY.GAMES, Nival и другие. У каждой свои процессы и стек.

Актуальные вакансии и требования смотрите на официальных страницах компаний.

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

FAQ

Нужен ли игровой опыт?

Желателен, но не обязателен — если есть сильная аналитическая база и готовность разобраться в предметке.

Нужен ли ML?

Для задач вроде предсказания оттока и LTV — часто да. Для классической продуктовой аналитики — не всегда.

Какой стек чаще всего?

SQL (ClickHouse, PostgreSQL), Python (pandas), BI-инструменты. У больших студий часто есть свои инструменты.