Функция PERCENTILE_CONT() в SQL: медиана и перцентили с интерполяцией

PERCENTILE_CONT() — это ordered-set агрегат: он сортирует значения и возвращает перцентиль с линейной интерполяцией между соседними точками. PERCENTILE_CONT(0.5) даёт медиану — устойчивую к выбросам замену среднему для перекошенных данных вроде выручки или времени сессии. Работает в PostgreSQL через конструкцию WITHIN GROUP (ORDER BY ...); в MySQL и SQLite её нет — там медиану считают через оконные функции. Для несуществующих в данных значений возвращает интерполированное число, в отличие от PERCENTILE_DISC.

Синтаксис

PERCENTILE_CONT(доля) WITHIN GROUP (ORDER BY выражение)

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

Пример 1: Медиана чека

SELECT
  PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) AS median_check
FROM orders;

Результат:

median_check
------------
1150.00

Пример 2: Медиана, p90 и p95 в одном запросе

SELECT
  PERCENTILE_CONT(0.5)  WITHIN GROUP (ORDER BY amount) AS p50,
  PERCENTILE_CONT(0.9)  WITHIN GROUP (ORDER BY amount) AS p90,
  PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY amount) AS p95
FROM orders;

Результат:

p50     | p90     | p95
--------+---------+---------
1150.00 | 4200.00 | 6100.00

Пример 3: Медиана чека по странам

SELECT
  country,
  PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) AS median_check
FROM orders
GROUP BY country
ORDER BY median_check DESC;

Результат:

country | median_check
--------+-------------
DE      | 1420.00
RU      | 1150.00
IN      |  780.00
Порешать SQL-задачи в тренажёре →

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

PERCENTILE_CONT интерполирует и может вернуть число, которого нет в данных (медиана из 10 и 20 будет 15) — если нужно реально существующее значение, бери PERCENTILE_DISC. Синтаксис особый: WITHIN GROUP (ORDER BY ...), а не обычные скобки с аргументом. В MySQL и SQLite функции нет вовсе, NULL игнорируются.

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

Спрашивают, когда среднее вводит в заблуждение из-за выбросов и нужна медиана или p90/p95 по времени ответа. Идёт в паре с PERCENTILE_DISC и GROUP BY; полезно знать, как посчитать медиану без неё через оконные функции.

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

Чем PERCENTILE_CONT отличается от PERCENTILE_DISC?

PERCENTILE_CONT интерполирует между соседними значениями и может вернуть число, которого нет в данных (медиана 10 и 20 → 15). PERCENTILE_DISC возвращает ближайшее реально существующее значение из набора. Для медианы непрерывных величин обычно берут CONT.

Работает ли PERCENTILE_CONT в MySQL и SQLite?

Нет. В PostgreSQL она есть через WITHIN GROUP, а в MySQL и SQLite такой функции нет. Медиану там считают оконными функциями — например, через ROW_NUMBER()/COUNT() или NTILE.

Как записать медиану через PERCENTILE_CONT?

Медиана — это 50-й перцентиль: PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount). Для p90 подставьте 0.9. Обратите внимание на конструкцию WITHIN GROUP — обычные скобки с аргументом здесь не работают.

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

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

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

Агрегации · Оконные функции

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

ROW_NUMBER · RANK · DENSE_RANK · LAG · LEAD · NTILE

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