Разбор задач из Озона для аналитиков

На собеседованиях любят простые по формулировке задачи, которые при этом сразу проверяют: понимаешь ли ты, как работает SQL и умеешь ли мыслить данными. Хочу разобрать две задачи, которые «встряхнули» меня на интервью. Первая — про JOIN‑ы, вторая — про пересчёт валют.

Задача 1

Две таблички с набором строк:

  • слева 4, 5, 6 (Tab 1)
  • справа 4, 4, 5, 5, (Tab 2)

Вопрос: скажите количество строк в результирующей таблице при 1. inner join 2. left join 3. cross join

Решение

  1. INNER JOIN берёт каждую строку из левой таблицы и ищет в правой все строки, где id совпадает. Если для одного значения в левой таблице есть несколько подходящих строк в правой — то SQL создаёт отдельную строку результата для КАЖДОГО совпадения. Это как правило умножения: 1 строка слева × N совпадений справа → N строк в результате.

У нас получается две строки: первая это 4,4; вторая 4;4 так как в табличке справа всего одно значение 4. Далее три пятерки также создают две строки. Всего 4 строки

  1. LEFT JOIN берёт все строки из левой таблицы (Tab 1) и “подклеивает” подходящие строки из Tab 2.
    Если совпадений нет → будет NULL в части Tab 2. Разберём:
    id=4 — 2 совпадения → 2 строки
    id=5 — 2 совпадения → 2 строки
    id=6 — нет совпадений → 1 строка (tab2.id = NULL)

Итого: 2 + 2 + 1 = 5 строк

  1. CROSS JOIN — декартово произведение: каждая строка Tab 1 умножается на каждую строку Tab 2. В Tab 1 — 3 строки, в Tab 2 — 4 строки. Итог: 3 × 4 = 12 строк

Задача 2. Пересчёт транзакций в рубли

Дано две таблицы:

transactions

  • id (int) — PK
  • date (date) — дата транзакции (может быть и выходной)
  • currency (varchar) — валюта
  • amount (float) — сумма в валюте

exchange

  • id (int) — PK
  • date (date) — дата публикации курса (только будние дни)
  • currency (varchar) — валюта
  • exc_cource (float) — курс валюты к рублю

Задача:

Добавить в transactions поле rub_amount = сумма в рублях.

  • если курс есть на дату транзакции — берём его,
  • если нет (например, выходные) — берём последний доступный курс до этой даты.

Основное затруднение

— Курс есть не на любую дату, а только на последние рабочие дни
— Поэтому на выходных берём последний курс до транзакции

Ошибочный путь

Я на собесе сначала пытался просто присоединить по дате и валюте. Но если транзакция попадает на выходной, курса на этот день нет → результат NULL.

Правильный алгоритм

  1. Для каждой транзакции фильтруем курсы по нужной валюте.
  2. Оставляем только те, где date <= дата транзакции.
  3. Берём курс с максимальной датой из этих.
  4. Умножаем amount * exc_cource.
Задача SQL для аналитика в Ozon
SELECT
    t.*,                            -- 1. Берём все поля из таблицы транзакций
    t.amount * e.exc_cource AS rub_amount     -- 2. Добавляем новый столбец: пересчёт суммы в рубли
FROM
    transactions t                            -- 3. Основная таблица транзакций
LEFT JOIN exchange e                          -- 4. Присоединяем таблицу курсов
    ON e.currency = t.currency                --    по совпадению валюты
    AND e.date = (                            --    и по дате:
        SELECT MAX(date)                      -- 5. Вложенный запрос: находим
        FROM exchange                         --    среди курсов
        WHERE currency = t.currency           --    по нужной валюте
          AND date <= t.date                  --    и не позже даты транзакции!
    )

Эта задача проверяет умение правильно «подбирать» данные, когда они неполные. На практике это встречается часто (календарные ряды, цены на дату, остатки складов).

Пошагово:

  • Читаем из transactions по одной строке.
  • Для каждой строки ищем ВСЕ курсы в exchange с этой валютой и датой не позже транзакции.
  • Среди них берём САМУЮ ПОЗДНЮЮ дату (MAX(date)).
  • Присоединяем найденную строку exchange к транзакции (по валюте и дате курса).
  • Считаем сумму в рублях.
  • Если курс не найден — rub_amount будет NULL (транзакция останется без курса).

Итог

Две задачи, простые на вид, позволяют показать логику:

  • Задача 1 тренирует понимание join‑ов.
  • Задача 2 — умение работать с неполными данными и аккуратно подбирать «последнее известное значение».

Именно такие кейсы на собесах отличают того, кто просто знает SQL‑синтаксис, от того, кто умеет применять его для аналитики.

Send
Share
Pin