SQL Academy · Урок

ROW_NUMBER, RANK, DENSE_RANK

Нумеруйте и ранжируйте строки внутри разделов и выбирайте подходящую функцию ранжирования при совпадении значений

Урок 2 из 413 шагов

«ROW_NUMBER, RANK, DENSE_RANK» — бесплатный урок SQL Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.

Три функции нумерации

Три оконные функции, которые нумеруют строки внутри секции:

  • ROW_NUMBER() — 1, 2, 3, 4 (всегда уникальные номера)
  • RANK() — 1, 2, 2, 4 (одинаковые значения получают общий номер, затем пропускается номер)
  • DENSE_RANK() — 1, 2, 2, 3 (одинаковые значения получают общий номер, пропусков нет)

ROW_NUMBER

Назначает номера 1, 2, 3 внутри каждой секции. Одинаковые значения разрешаются произвольно — для предсказуемого результата добавьте дополнительный критерий в ORDER BY:

SELECT id, user_id, total,
       ROW_NUMBER() OVER (
         PARTITION BY user_id ORDER BY total DESC, id
       ) AS rn
FROM orders;

Первые N в каждой группе

Классическое применение ROW_NUMBER:

WITH ranked AS (
  SELECT *,
         ROW_NUMBER() OVER (
           PARTITION BY user_id ORDER BY total DESC
         ) AS rn
  FROM orders
)
SELECT * FROM ranked WHERE rn <= 3;
-- Each user's top 3 orders.

RANK

Строки с одинаковым значением ORDER BY получают одинаковый ранг; следующее отличающееся значение пропускает соответствующее количество позиций:

-- totals: 100, 90, 90, 70
-- RANK:    1,   2,  2,  4    (skipped 3)
SELECT id, total,
       RANK() OVER (ORDER BY total DESC) AS rk
FROM orders;

DENSE_RANK

То же, что и RANK, но без пропусков:

-- totals: 100, 90, 90, 70
-- DENSE:   1,   2,  2,  3
SELECT id, total,
       DENSE_RANK() OVER (ORDER BY total DESC) AS dr
FROM orders;

Как выбрать подходящую функцию

  • Нужны уникальные номера (например, для постраничного вывода)? ROW_NUMBER
  • Нужна традиционная нумерация с пропусками при одинаковых значениях? RANK
  • Нужна нумерация без пропусков при одинаковых значениях? DENSE_RANK

NTILE: группы по квантилям

NTILE(n) распределяет строки по n примерно равным группам:

SELECT id, total,
       NTILE(4) OVER (ORDER BY total) AS quartile
FROM orders;
-- 1 = bottom 25%, 4 = top 25%

Удаление дублирующихся строк

Используйте ROW_NUMBER + DELETE, чтобы оставить одну строку в каждой группе дубликатов:

WITH dups AS (
  SELECT id,
         ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rn
  FROM users
)
DELETE FROM users WHERE id IN (SELECT id FROM dups WHERE rn > 1);

Постраничный вывод для каждой группы

Вторая страница в списке «заказы каждого пользователя, по 5 на страницу»:

WITH r AS (
  SELECT id, user_id,
         ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn
  FROM orders
)
SELECT * FROM r WHERE rn BETWEEN 6 AND 10;

PERCENT_RANK и CUME_DIST

Относительная позиция внутри секции:

SELECT id, total,
       PERCENT_RANK() OVER (ORDER BY total) AS pct_rank,
       CUME_DIST()    OVER (ORDER BY total) AS cume_dist
FROM orders;

Производительность

Функциям нумерации нужны отсортированные входные данные внутри каждой секции. Индекс по (partition_col, order_col) может избавить от сортировки.

Итоги

Три функции нумерации покрывают большинство потребностей.

  • ROW_NUMBER — для уникальных номеров
  • RANK / DENSE_RANK — для ранжирования с одинаковыми значениями
  • NTILE — для групп по квантилям

Быстрая проверка

Для значений 100, 90, 90, 70 какой результат выдаст DENSE_RANK?

Можно начать бесплатно

Изучай SQL с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
46
Уроки
183

Часто задаваемые вопросы

Урок «ROW_NUMBER, RANK, DENSE_RANK» бесплатный?

Да — полный текст урока «ROW_NUMBER, RANK, DENSE_RANK» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.

Чему я научусь в уроке «ROW_NUMBER, RANK, DENSE_RANK»?

Нумеруйте и ранжируйте строки внутри разделов и выбирайте подходящую функцию ранжирования при совпадении значений Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать SQL Academy?

Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «ROW_NUMBER, RANK, DENSE_RANK»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке SQL Academy?

Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. OVER, PARTITION BY, ORDER BY
  2. ROW_NUMBER, RANK, DENSE_RANK
  3. LAG, LEAD и шаблоны временных рядов
  4. Накопительные итоги и скользящие средние
← Назад к SQL Academy