Оконные функции

Ранжирование: ROW_NUMBER, RANK, DENSE_RANK

Содержание курса

ROW_NUMBER, RANK, DENSE_RANK: поведение при одинаковых значениях сортировки

Разница между тремя функциями видна только тогда, когда несколько строк имеют одинаковое значение ключа сортировки. Возьмём таблицу scores с четырьмя игроками:

CREATE TABLE scores (
    id     INTEGER PRIMARY KEY,
    player TEXT,
    score  INTEGER
);
INSERT INTO scores VALUES
    (1, 'Аня',  90),
    (2, 'Боря', 85),
    (3, 'Вася', 85),
    (4, 'Галя', 70);

Запрос:

SELECT
    id,
    player,
    score,
    ROW_NUMBER() OVER (ORDER BY score DESC, id) AS rn,
    RANK()       OVER (ORDER BY score DESC)      AS rnk,
    DENSE_RANK() OVER (ORDER BY score DESC)      AS drnk
FROM scores
ORDER BY score DESC, id;

Результат:

player score rn rnk drnk
Аня 90 1 1 1
Боря 85 2 2 2
Вася 85 3 2 2
Галя 70 4 4 3

Посмотрим на каждую функцию отдельно.

ROW_NUMBER добавляет вторичный ключ id в своё ORDER BY — иначе Боря и Вася получили бы номера 2 и 3 в неизвестном порядке. С id порядок детерминирован: 1, 2, 3, 4 без пробелов и без дублей. Функции безразлично, что у Бори и Васи одинаковый score; она просто нумерует строки по указанному порядку.

RANK не получает вторичного ключа, поэтому Боря и Вася с одинаковым score делят одно место и оба получают ранг 2. Следующий ранг вычисляется по формуле «1 + число строк, стоящих раньше»: перед Галей стоят три строки (Аня, Боря, Вася), поэтому её ранг —

  1. Число 3 пропущено навсегда.

DENSE_RANK тоже ставит Борю и Васю на ранг 2, но следующий ранг всегда увеличивается на 1 независимо от размера группы равных. Галя получает 3, а не 4. Последовательность рангов плотная: пробелов нет.

Практически это означает: если вам нужно выбрать строки с «топ-3 позициями», DENSE_RANK() <= 3 может вернуть больше трёх строк (когда несколько строк делят одно место), а RANK() <= 3 — то же самое, но ранг 3 при наличии группы равных на 2-м месте уже недостижим и вы потеряете целую позицию. ROW_NUMBER() <= 3 возвращает не более трёх строк; если строк хотя бы три, их будет ровно три. При равных значениях выбор между ними произволен, если в оконном ORDER BY нет дополнительного уникального критерия.

Анимация заполнения ROW_NUMBER, RANK и DENSE_RANK для четырёх участников с одинаковыми результатами у первых двух
Одинаковые значения по-разному влияют на три вида ранга

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.