Функция DENSE_RANK() в SQL: синтаксис, примеры, отличие от RANK

DENSE_RANK() — оконная функция ранжирования, которая при одинаковых значениях присваивает одинаковый ранг, но следующий ранг не пропускает. Для значений 100, 100, 90 ранги будут 1, 1, 2 (у RANK было бы 1, 1, 3). «Плотные» ранги удобны, когда нужны уровни без дыр — например, топ-N уникальных цен или зарплатных грейдов.

Синтаксис

DENSE_RANK() OVER (PARTITION BY колонки ORDER BY колонки)

Примеры использования

Пример 1: Топ-3 уникальных цены (даже если товаров больше)

SELECT * FROM (
  SELECT product, price,
         DENSE_RANK() OVER (ORDER BY price DESC) AS dr
  FROM products
) t
WHERE dr <= 3;

Результат:

product | price | dr
A       | 990   | 1
B       | 990   | 1
C       | 750   | 2
D       | 500   | 3

Пример 2: Плотный ранг зарплат по отделам

SELECT dept, name, salary,
       DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dr
FROM employees;

Результат:

dept | name | salary | dr
IT   | Аня  | 200    | 1
IT   | Boris| 200    | 1
IT   | Вера | 150    | 2
Порешать SQL-задачи в тренажёре →

Типичная ошибка

DENSE_RANK не гарантирует ровно N строк: под dr <= 3 могут попасть 5 строк, если есть ничьи. Если нужно строго N записей — используй ROW_NUMBER. И помни: как и все окна, DENSE_RANK нельзя фильтровать прямо в WHERE — только через подзапрос или CTE.

Где спрашивают на собеседовании

Вопрос «топ-N уникальных значений» почти всегда про DENSE_RANK. На собеседовании покажи, что понимаешь разницу между «топ-3 строки» (ROW_NUMBER), «топ-3 позиции с ничьими» (RANK) и «топ-3 уникальных уровня» (DENSE_RANK).

FAQ: частые вопросы про DENSE_RANK

Чем DENSE_RANK отличается от RANK?

Оба дают одинаковый ранг при равных значениях, но RANK пропускает следующие номера на число ничьих, а DENSE_RANK идёт подряд без пропусков.

Как выбрать топ-N уникальных значений?

Именно DENSE_RANK: он присваивает уникальным значениям плотные уровни 1, 2, 3, поэтому dr <= N вернёт ровно N уникальных значений (со всеми их строками).

DENSE_RANK есть в SQLite?

Да, оконные функции, включая DENSE_RANK, поддерживаются в SQLite с версии 3.25 и в PostgreSQL. В тренажёре обе доступны.

Задачи в тренажёре по теме

Вопросы с собеседований по теме

Смежные темы SQL

Оконные функции · Ранжирование

Другие функции SQL

ROW_NUMBER · RANK · LAG · LEAD · NTILE · SUM OVER

Открыть SQL-тренажёр (565 задач) →