SQLLab
Все статьи

SQL тест для Data Scientist: что должен знать

Какой уровень SQL ожидать от Data Scientist на собеседовании: темы, задачи, отличие от требований к аналитику данных.

22 февраля 2026 г.·4 мин чтения·

Data Scientist — не аналитик и не разработчик. SQL для него инструмент подготовки данных, а не основная специальность. Тем не менее без уверенного SQL дата-сайентист становится зависим от дата-инженеров при каждом обращении к данным.

Какой SQL нужен Data Scientist

Требования к SQL у DS отличаются от требований к аналитику данных. DS реже строит регулярные отчёты, зато чаще:

  • Выгружает данные для обучения моделей
  • Формирует признаки (feature engineering) через SQL
  • Проверяет гипотезы на исторических данных
  • Анализирует качество данных (пропуски, выбросы, дубликаты)

Для этого нужны: сложные JOIN, подзапросы, оконные функции, работа с датами, базовая статистика в SQL.

Что НЕ нужно проверять у Data Scientist

В отличие от позиции бэкенд-разработчика, DS не нужно знать:

  • DDL (CREATE TABLE, ALTER TABLE) на продвинутом уровне
  • Управление транзакциями
  • Настройку индексов
  • Детали репликации и партиционирования

Базовое понимание этих тем желательно, но не критично.

Задача 1: Подготовка обучающего датасета

-- Задача: сформируйте датасет для обучения модели оттока клиентов.
-- Нужны: customer_id, дни с последней покупки, число покупок за 90 дней,
-- средний чек, флаг оттока (нет покупок за последние 30 дней)

SELECT
    c.id                                                     AS customer_id,
    CURRENT_DATE - MAX(o.order_date)::DATE                   AS days_since_last_order,
    COUNT(CASE WHEN o.order_date >= CURRENT_DATE - 90
               THEN 1 END)                                   AS orders_last_90d,
    ROUND(AVG(o.amount), 2)                                  AS avg_order_amount,
    CASE WHEN MAX(o.order_date) < CURRENT_DATE - 30
         THEN 1 ELSE 0 END                                   AS is_churned
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.id;

Что проверяем: сложная агрегация, работа с датами, CASE для бинарного признака.

Задача 2: Анализ качества данных

-- Задача: найдите проблемы в таблице транзакций:
-- - NULL-значения в ключевых полях
-- - дубликаты по (user_id, transaction_id)
-- - транзакции с отрицательными суммами
-- - транзакции в будущем

SELECT 'null_user_id'       AS issue, COUNT(*) AS count
FROM transactions WHERE user_id IS NULL
UNION ALL
SELECT 'null_amount',        COUNT(*) FROM transactions WHERE amount IS NULL
UNION ALL
SELECT 'negative_amount',    COUNT(*) FROM transactions WHERE amount < 0
UNION ALL
SELECT 'future_date',        COUNT(*) FROM transactions WHERE transaction_date > CURRENT_DATE
UNION ALL
SELECT 'duplicates',
       COUNT(*) - COUNT(DISTINCT (user_id, transaction_id))
FROM transactions;

Что проверяем: UNION ALL для сводного отчёта, разнообразие условий фильтрации.

Задача 3: Feature Engineering с оконными функциями

-- Задача: для каждой сессии пользователя вычислите:
-- - порядковый номер сессии
-- - время с предыдущей сессии (в днях)
-- - скользящее среднее длительности за 3 сессии

SELECT
    user_id,
    session_date,
    duration_min,
    ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY session_date)   AS session_num,
    session_date - LAG(session_date) OVER (
        PARTITION BY user_id ORDER BY session_date
    )                                                                 AS days_since_prev,
    AVG(duration_min) OVER (
        PARTITION BY user_id
        ORDER BY session_date
        ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
    )                                                                 AS rolling_avg_3s
FROM sessions;

Что проверяем: комплексное применение оконных функций для feature engineering.

Задача 4: Сегментация по RFM

RFM (Recency, Frequency, Monetary) — базовая модель сегментации клиентов, которую DS часто реализует в SQL:

WITH rfm_raw AS (
    SELECT
        customer_id,
        CURRENT_DATE - MAX(order_date)::DATE           AS recency,
        COUNT(*)                                       AS frequency,
        SUM(amount)                                    AS monetary
    FROM orders
    GROUP BY customer_id
),
rfm_scored AS (
    SELECT *,
           NTILE(5) OVER (ORDER BY recency ASC)    AS r_score,   -- меньше дней = лучше
           NTILE(5) OVER (ORDER BY frequency DESC) AS f_score,
           NTILE(5) OVER (ORDER BY monetary DESC)  AS m_score
    FROM rfm_raw
)
SELECT
    customer_id,
    recency, frequency, monetary,
    r_score, f_score, m_score,
    r_score + f_score + m_score AS rfm_total
FROM rfm_scored
ORDER BY rfm_total DESC;

Что проверяем: CTE, NTILE, понимание бизнес-задачи.

Статистические функции в PostgreSQL

Для DS важно знать статистические возможности SQL:

-- Базовая статистика
SELECT
    AVG(amount)           AS mean,
    STDDEV(amount)        AS std_dev,
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) AS median,
    PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY amount) AS q1,
    PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY amount) AS q3
FROM orders;

Кандидат-DS должен знать разницу между AVG и MEDIAN, понимать выбросы.

Шкала оценки для Data Scientist

НавыкВажностьПроверка
Сложные JOIN (3+ таблицы)ВысокаяЗадача на формирование датасета
Оконные функцииВысокаяFeature engineering
Работа с датамиВысокаяПодготовка временных признаков
CTEСредняяСтруктурирование сложного запроса
Статистические функцииСредняяБазовая EDA через SQL
Оптимизация запросовНизкаяОбщее понимание

Для DS проходной балл по SQL обычно ниже, чем для аналитика данных — при условии сильного Python/ML бэкграунда.

Кандидаты DS часто имеют пробелы именно в SQL. Порекомендуйте им SQLlab.ru для быстрого заполнения этих пробелов перед собеседованием.

Похожие статьи

Попробуй на практике

Тренажёр с реальными задачами — бесплатно и без регистрации

Открыть тренажёр →