Справочник по функциям

DENSE_RANK

Возвращает ранг строки в разделе окна, как RANK, но без пропусков в нумерации мест.

MySQL 8.1
DENSE_RANK() OVER ([PARTITION BY ...] [ORDER BY ...])

Параметры

PARTITION BYнеобязательный
Столбцы, по которым строки делятся на разделы, ранги считаются в каждом отдельно
ORDER BYнеобязательный
Порядок строк, по которому определяется место; без него у всех строк ранг 1

Возвращаемое значение

Целое число (BIGINT UNSIGNED) — место строки; одинаковые значения делят место, следующее место больше на единицу: 1, 2, 2, 3

Примеры

DENSE_RANK и RANK по статусу

MySQL 8.1
SELECT member_name,
	status,
	RANK() OVER (
		ORDER BY status
	) AS status_rank,
	DENSE_RANK() OVER (
		ORDER BY status
	) AS status_dense_rank
FROM FamilyMembers;
member_namestatusstatus_rankstatus_dense_rank
Lela Quinceydaughter11
Annie Quinceydaughter11
Wednesday Addamsdaughter11
Headley Quinceyfather42
Ernest Forrestfather42
Flavia Quinceymother63
Constance Forrestmother63
Andie Quinceyson84

Самые дорогие товары в каждой категории

MySQL 8.1
SELECT category,
	name,
	price
FROM (
		SELECT category,
			name,
			price,
			DENSE_RANK() OVER (
				PARTITION BY category
				ORDER BY price DESC
			) AS price_rank
		FROM products
	) AS ranked
WHERE price_rank = 1;
categorynameprice
DrinksGreen Smoothie6.99
FoodSushi Set24.99
GroceryOlive Oil 500ml7.99
SnacksDark Chocolate4.49

Подробности

Удобна для поиска N-го по величине значения: строки с DENSE_RANK() = 2 содержат второе значение, даже если первое встречается несколько раз. Фильтровать по рангу нужно во внешнем запросе: в WHERE того же запроса оконные функции использовать нельзя.

Смотрите также

Где изучить