RANK vs ROW_NUMBER: разница с примерами для собеса
ROW_NUMBER и RANK — оконные функции, обе нумеруют строки внутри партиции. Главное отличие — поведение при одинаковых значениях. На собесе часто просят вернуть «по одной записи из каждой группы» — это вопрос про ROW_NUMBER.
Если коротко. ROW_NUMBER всегда возвращает уникальные номера (1,2,3,4), RANK при ничьих ставит одинаковый номер и пропускает следующие (1,1,3,4).
Проверь себя · 1/3разбор после ответа
Вы делаете рейтинг товаров по выручке внутри категории. Если два товара делят 2 место, следующий товар должен получить 3 место (без пропуска). Какая функция подходит лучше всего?
RANK vs ROW_NUMBER: таблица различий
Когда использовать RANK
- Нужен строго уникальный номер для каждой строки в партиции.
- Хотите достать «первую» запись в каждой группе (топ-1 по дате).
- Делаете дедуп — оставляем строку с rn = 1.
Когда использовать ROW_NUMBER
- Нужно сохранить «справедливость» нумерации при ничьих.
- Считаете спортивный рейтинг или олимпиаду.
- Хотите явно увидеть, что были одинаковые значения.
На примере
RANK — с пропусками при ничьих
SELECT user_id, revenue,
RANK() OVER (ORDER BY revenue DESC) AS r
FROM users;ROW_NUMBER — уникальный порядок
SELECT user_id, revenue,
ROW_NUMBER() OVER (PARTITION BY country ORDER BY revenue DESC) AS rn
FROM users
QUALIFY rn = 1; -- по одному пользователю на странуЛовушка на собесе
Любимый вопрос — «как взять последний заказ каждого пользователя?». Ответ: ROW_NUMBER с PARTITION BY user_id ORDER BY ordered_at DESC и фильтр rn = 1. RANK тут опасен из-за ничьих.