Перейти к основному содержимому

SQL RANK(): как упорядочить строки с примерами

Узнайте, как использовать функцию SQL RANK() для присвоения рейтингов строкам, обработки ничьих и сравнения с DENSE_RANK() и ROW_NUMBER().
Обновлено 4 мая 2026 г.  · 6 мин читать

При работе с SQL сортировка данных проста: вы можете использовать ORDER BY, чтобы упорядочить строки. Однако простая сортировка не показывает положение каждой строки внутри этого порядка. Здесь и пригодится ранжирование. Вместо того чтобы просто смотреть на отсортированные данные, вы можете присвоить каждой строке позицию — например, 1-ю, 2-ю или 3-ю — по определённым критериям.

Функция RANK() решает эту задачу, присваивая каждой строке числовой ранг в соответствии с заданным порядком. RANK() относится к оконным функциям SQL, которые позволяют выполнять вычисления по набору строк, при этом возвращая результаты по каждой строке. 

В этом руководстве я покажу синтаксис RANK(), практические примеры, разберу, как функция обрабатывает совпадения, и сравню её с похожими функциями DENSE_RANK() и ROW_NUMBER().

Если вы новичок в SQL, начните с нашего курса Introduction to SQL, или курса Intermediate SQL, если у вас уже есть некоторый опыт. 

Что такое функция SQL RANK()?

Функция SQL RANK() — это оконная функция, которая присваивает каждой строке ранг на основе указанного порядка. Ранжирование полностью определяется ORDER BY внутри оконной функции. То есть каждой строке присваивается позиция 1, 2, 3 и так далее в соответствии с выражением ORDER BY.

Обратите внимание, что при использовании RANK():

  • Строки с одинаковым значением (ничьи) получают одинаковый ранг.
  • При наличии ничьих в последовательности рангов появляются пропуски. Например, если две строки имеют ранг 2, следующий ранг будет 4, а не 3.

Синтаксис SQL RANK()

Базовый синтаксис функции RANK() выглядит так:

RANK() OVER (ORDER BY column)

Где:

  • OVER: определяет окно (набор строк), по которому работает функция.

  • ORDER BY: задаёт, как применяется ранжирование, например от наибольшего к наименьшему.

  • PARTITION BY (необязательно): разбивает данные на группы и ранжирует строки отдельно в каждой группе.

Ниже приведён синтаксис функции RANK() с предложением PARTITION BY:

RANK() OVER (PARTITION BY column1 ORDER BY column2)

Функция SQL RANK() широко поддерживается основными СУБД, включая PostgreSQL, MySQL (8.0+), Microsoft SQL Server и Oracle Database. Синтаксис в основном единообразен между этими системами, поскольку он является частью стандарта ANSI SQL.

Базовый пример SQL RANK()

Разобравшись с синтаксисом функции RANK(), давайте посмотрим простой пример её работы.

Предположим, у вас есть таблица employees с информацией о зарплате каждого сотрудника.

Таблица сотрудников.

Вы можете использовать следующий запрос, чтобы ранжировать сотрудников по уровню зарплаты.

-- Rank employees by salary
SELECT 
    name,
    salary,
    RANK() OVER (ORDER BY salary DESC) AS rank_position
FROM employees;

В этом запросе строки упорядочены по зарплате по убыванию, поэтому наивысшая зарплата получает ранг 1. Если две строки имеют одинаковую зарплату, они получают одинаковый ранг.

Использование функции RANK() в SQL.

Вы заметите, что если две строки имеют одинаковые значения, они получают одинаковый ранг.

Затем следующий ранг пропускается. SQL учитывает ничью, пропуская следующее значение ранга.

Рекомендую пройти наш курс Introduction to SQL Server, чтобы узнать больше о группировке и агрегировании данных.

SQL RANK() с PARTITION BY

Как мы уже узнали, предложение PARTITION BY позволяет применять ранжирование внутри групп, а не по всему набору данных.

В примере ниже сотрудники сгруппированы по полю department, и ранжирование начинается заново в каждом отделе. Таким образом, у каждой группы своя независимая последовательность рангов.

-- Rank employees within each department
SELECT 
    name,
    department,
    salary,
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;

Использование SQL RANK() с PARTITION BY

Из результатов видно, что в отделе «Sales» и Emily Johnson, и Michael Brown делят 1-й ранг, а в отделе «HR» William Miller и Olivia Wilson также делят 1-й ранг.

SQL RANK() vs. DENSE_RANK() vs. ROW_NUMBER()

При ранжировании данных в SQL вы можете использовать RANK(), DENSE_RANK() или ROW_NUMBER(). Эти функции выглядят схоже, но ведут себя так:

  • RANK(): ничьи получают одинаковый ранг, поэтому после них возникают пропуски.

  • DENSE_RANK(): ничьи получают одинаковый ранг, но без пропусков в последовательности.

  • ROW_NUMBER(): каждая строка получает уникальный номер без ничьих, даже при равных значениях.

Чтобы лучше понять различия, выполните сравнительный запрос ниже:

-- Compare RANK() vs DENSE_RANK() vs ROW_NUMBER()
SELECT 
    name,
    salary,

    RANK() OVER (ORDER BY salary DESC) AS rank_val,          -- allows gaps after ties

    DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank1,  -- no gaps, consecutive ranks

    ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num      -- always unique sequence

FROM employees;

SQL RANK() vs. DENSE_RANK() vs. ROW_NUMBER()

Исходя из этих результатов, вы можете:

  • Использовать RANK(), когда важна позиция и допустимы пропуски.

  • Использовать DENSE_RANK(), когда нужен непрерывный ряд рангов.

  • Использовать ROW_NUMBER(), когда каждой строке нужен уникальный номер, например для пагинации данных.

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

Функция SQL RANK() особенно полезна, когда нужно упорядочить данные и при этом естественно обработать ничьи. Также она важна в следующих случаях:

  • Таблицы лидеров: когда нужно ранжировать игроков или пользователей по очкам, допускаючи ничьи при равных результатах.
  • Ранжирование продаж: если вы хотите определить лучших сотрудников или регионы по выручке, даже при равных показателях.
  • Определение топ-N значений: полезно для запросов вроде «топ-3 зарплаты», особенно когда нужно включить ничьи.

Распространённые ошибки при работе с SQL RANK()

Вот некоторые ошибки, с которыми я сталкивался при использовании SQL RANK(), и как их избежать:

  • Забытый ORDER BY: без предложения ORDER BY ранжирование не имеет определённой логики и может вернуть неожиданные результаты.

  • Непонимание поведения при ничьих: новички могут ожидать 1, 2, 2, 3, но RANK() создаёт пропуски (1, 2, 2, 4) в рангах.

  • Использование RANK(), когда нужен ROW_NUMBER(): если требуются уникальные последовательные значения, лучше выбрать ROW_NUMBER().

  • Неиспользование PARTITION BY при необходимости: без разбиения ранжирование выполняется глобально, а не внутри групп.

Рекомендации по использованию SQL RANK()

Чтобы ваши запросы были чистыми и давали ожидаемые результаты, рекомендую соблюдать следующие практики при использовании функции SQL RANK():

  • Всегда задавайте чёткий порядок: явно указывайте в ORDER BY, например DESC, чтобы избежать неоднозначного ранжирования.

  • Выбирайте правильную функцию ранжирования: используйте RANK(), DENSE_RANK() или ROW_NUMBER() в зависимости от того, как нужно обрабатывать ничьи.

  • Тестируйте сценарии с ничьими: перед выводом в продакшен проверьте, как ведут себя данные при наличии дубликатов значений.

  • Комбинируйте с фильтрацией: поскольку использовать RANK() напрямую в WHERE нельзя, оборачивайте запрос с ранжированием в подзапрос или CTE, когда нужно отфильтровать «Top N».

Заключение

RANK() — полезный инструмент для упорядоченных сравнений в SQL, особенно когда нужно учитывать реальные сценарии с равными значениями. Важно понимать, как функция обрабатывает ничьи и почему ранги могут повторяться и пропускать номера. Освоив это поведение, вы сможете выбирать её или альтернативы — DENSE_RANK() и ROW_NUMBER() — в зависимости от задач.

Теперь, когда вы узнали, как ранжировать данные в SQL, рекомендую ознакомиться с нашим карьерным треком Associate Data Analyst in SQL, если вы хотите стать компетентным аналитиком данных и освоить необходимые навыки. Курс Reporting in SQL также подойдёт, если вы хотите научиться создавать профессиональные дашборды на SQL.

SQL RANK() — ответы на частые вопросы

Чем RANK() отличается от ORDER BY?

ORDER BY только сортирует строки, а RANK() после сортировки присваивает каждой строке числовую позицию.

Почему в результатах RANK() есть пропуски?

В результатах RANK() могут появляться пропуски, потому что при ничьих несколько строк получают одинаковый ранг, из-за чего следующий ранг смещается.

В чём разница между RANK() и DENSE_RANK()?

RANK() создаёт пропуски после ничьих, тогда как DENSE_RANK() присваивает последовательные ранги без пропусков.

В чём разница между RANK() и ROW_NUMBER()?

RANK() допускает ничьи, а ROW_NUMBER() присваивает каждой строке уникальный номер вне зависимости от дубликатов.

Поддерживается ли RANK() во всех базах данных?

Большинство современных СУБД поддерживают RANK(), включая PostgreSQL, MySQL (8.0+), Microsoft SQL Server и Oracle Database.

Темы

Изучайте SQL с DataCamp

Course

Data Manipulation in SQL

4 ч
320.1K
Master the complex SQL queries necessary to answer a wide variety of data science questions and prepare robust data sets for analysis in PostgreSQL.
ПодробнееRight Arrow
Начать курс
Смотрите большеRight Arrow