Ко всем темам
Тематический маршрут

SQL для ML и аналитики

Какие реальные SQL-секции пройти от базовых конструкций до окон, временных рядов и Top-K?

Фильтрация и агрегация, соединения, оконные функции, задачи по времени и аккуратная проверка неоднозначных условий.

3 реальных собеседования2 вопроса6 подтем

Маршрут из трёх собеседований

Проходите по порядку: база → глубина → применение.

Начать отсюдаДата не указана

Собирает основу темы и задаёт правильную структуру ответа.

Технический экран: SQL, Python и ML/DL-теория

Начинается с короткой проверки WHERE/HAVING, UNION ALL и оконных функций, затем переходит к выбору последнего устройства пользователя.

Middle Аудио · 48 мин 2 ключевых этапа 3 шага практики

После прохождения

  • Различать фильтрацию строк и групп
  • Надёжно выбирать последнюю запись с явным порядком
Фильтрация и агрегацияСоединенияОконные функцииВремя и интервалы
Углубитьсяапрель 2026 г.

Добавляет сложные уточняющие вопросы и проверяет глубину понимания.

Dodo: Техническое собеседование

Dodo

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

Middle / Senior 2 ключевых этапа 3 шага практики

После прохождения

  • Строить календарное окно без утечки будущего
  • Разбирать длинное условие на проверяемые CTE
СоединенияОконные функцииВремя и интервалыПроверка корректности
Закрепить на практикеапрель 2026 г.

Переводит знания в написание кода или полноценный прикладной кейс.

Техническое собеседование в Raiffeisen: метрики, теория ML и SQL Top-K

Raiffeisen Bank

Практическая задача на Top-50 товаров для каждого пользователя, а затем тот же контракт обсуждается в Pandas и в масштабе миллионов эмбеддингов.

Middle Аудио · 48 мин 2 ключевых этапа 8 шагов практики

После прохождения

  • Написать Top-K по группам через оконную функцию
  • Сверить SQL-контракт с эквивалентной обработкой в Pandas
Оконные функцииTop-K по группамПроверка корректности

Что покрывает каждое интервью

Матрица построена по конкретным вопросам и этапам, а не по совпадению слов в заголовке.

ПодтемаНачать отсюдаУглубитьсяЗакрепить на практике
Фильтрация и агрегацияWHERE, GROUP BY, HAVING и порядок выполнения запроса.Глубоко
СоединенияJOIN, самосоединение и присоединение справочников без размножения строк.Рабочее пониманиеГлубоко
Оконные функцииROW_NUMBER, ранжирование и вычисления без потери строк.ГлубокоГлубокоГлубоко
Время и интервалыПоследнее событие, календарные окна и пропущенные даты.Рабочее пониманиеГлубоко
Top-K по группамРанжирование внутри пользователя или категории и устойчивые tie-breakers.Глубоко
Проверка корректностиГраницы окна, дубликаты, NULL и неоднозначность постановки.ГлубокоРабочее понимание

Отдельная практика по теме

Раскрывайте вопросы и сверяйте ответы прямо здесь. Задачи открываются отдельно в редакторе.

Ключевые вопросы маршрута

Формулировка

Чем отличаются WHERE и HAVING, когда нужен UNION ALL и как оконная функция считает агрегат, не схлопывая строки?

Короткий ответ

WHERE фильтрует строки до группировки, HAVING — группы после агрегирования. UNION ALL объединяет результаты без удаления дублей. Оконная функция считает значение по партиции, но сохраняет исходную детализацию строк.

Логический порядок помогает не путаться: FROM/JOIN формирует строки, WHERE отбрасывает строки, GROUP BY создаёт группы, агрегаты вычисляются по группам, HAVING отбрасывает группы, а SELECT и ORDER BY формируют результат. Поэтому условие по исходному столбцу обычно относится к WHERE, а условие COUNT(*) > 5 — к HAVING.

UNION удаляет дубли и требует дополнительной работы, тогда как UNION ALL просто добавляет строки второго результата и обычно предпочтительнее, если уникальность не нужна. Оконная функция с OVER(PARTITION BY ... ORDER BY ...) вычисляет ранг, накопительную сумму или соседнее значение для каждой строки. Она не заменяет GROUP BY: группировка уменьшает число строк, окно сохраняет их и добавляет аналитический столбец.

Полная карточка: теория, ошибки и прогресс

Формулировка

Есть DataFrame с колонками user_id, item_id и score. Как оставить для каждого пользователя 50 товаров с наибольшим score?

Короткий ответ

Отсортируйте строки по user_id и score по убыванию, затем возьмите первые 50 строк каждой группы через groupby("user_id").head(50).

Базовый вариант:

result = (
    df.sort_values(["user_id", "score", "item_id"], ascending=[True, False, True])
      .groupby("user_id", sort=False, group_keys=False)
      .head(50)
)

Дополнительная сортировка по item_id делает результат детерминированным при одинаковых score. Если по условию нужно включать все товары, разделившие 50-е место, используйте rank внутри user_id с подходящим методом и отфильтруйте rank <= 50.

Глобальная сортировка обычно стоит O(n log n). На больших данных операцию лучше выполнять в SQL или распределённом движке.

Полная карточка: теория, ошибки и прогресс

Задачи из этих интервью

Повторить теорию перед практикой