Собесов

StrataScratch (Uber) — третья транзакция каждого пользователя

SQLN-я транзакция per groupСредняяMiddle

Условие

Таблица uber_transactions(user_id, transaction_date, amount). Для каждого пользователя верните третью по времени транзакцию (если есть). Поля: user_id, transaction_date, amount.

Решение

WITH ranked AS (
  SELECT
    user_id, transaction_date, amount,
    ROW_NUMBER() OVER (
      PARTITION BY user_id
      ORDER BY transaction_date ASC
    ) AS rn
  FROM uber_transactions
)
SELECT user_id, transaction_date, amount
FROM ranked
WHERE rn = 3;

Тай-брейк

Если у пользователя две транзакции в один день — порядок недетерминирован. Чтобы стабилизировать — добавить второй ключ:

ORDER BY transaction_date ASC, amount DESC

или ORDER BY transaction_id, если он есть.

RANK / DENSE_RANK тут НЕ подходят

RANK = 3 пропустит юзеров, у которых первые две транзакции в один день (получат RANK = 1, 1, 3 — третья будет, но не строго «третья по счёту»). Для «третьей по счёту» — только ROW_NUMBER.

Подводные камни

  1. Пользователи с < 3 транзакций. Просто не появятся в выходе. Если нужны NULL для них — LEFT JOIN с таблицей пользователей.
  2. Несколько транзакций в один день. ROW_NUMBER даст разный «третий» при каждом запуске, если нет дополнительного ORDER BY.
  3. Сортировка ASC vs DESC. «Третья» — обычно по времени снизу вверх (1-я, 2-я, 3-я). Не путайте с «третьей с конца».

Эталонный ответ

ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY transaction_date) → фильтр = 3. С тай-брейком по второму полю.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти