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: таблица различий

ПараметрRANKROW_NUMBER
УникальностьНе уникальнаУникальна
Поведение при ничьейОдинаковый номер + пропускПорядок определяется тай-брейкером
Пример (10,10,8)1, 1, 31, 2, 3
Для top-N с дедупомОпасноИдеально
Для рейтинговЕстественноНе показывает ничьи

Когда использовать RANK

Когда использовать 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 тут опасен из-за ничьих.
Тренировать SQL в Telegram

Ещё сравнения по теме