Как найти медиану в SQL без использования встроенной функции медианы?

«Как найти медиану в SQL без использования встроенной функции медианы?» — вопрос из категории SQL, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Медиану можно вычислить, используя оконные функции для нумерации строк и определения центральных позиций. Вот универсальный подход, работающий в PostgreSQL, MySQL 8+, SQL Server и других СУБД с поддержкой оконных функций:

WITH ranked_data AS (
    SELECT
        value,
        ROW_NUMBER() OVER (ORDER BY value) AS row_asc,
        COUNT(*) OVER () AS total_count
    FROM your_table
)
SELECT
    AVG(value) AS median
FROM ranked_data
WHERE
    row_asc IN (
        (total_count + 1) / 2,          -- Центральный элемент для нечетного N
        (total_count + 2) / 2           -- Второй центральный элемент для четного N
    );

Как это работает:

  1. ROW_NUMBER() присваивает порядковый номер каждой строке после сортировки по значению.
  2. COUNT(*) OVER () вычисляет общее количество строк.
  3. Условие WHERE выбирает одну или две центральные строки. Для нечетного total_count оба выражения дают одинаковый номер строки. Для четного — выбираются две средние строки.
  4. AVG(value) усредняет значения выбранных строк, что корректно дает медиану как для четного, так и для нечетного количества записей.

Альтернатива для СУБД с PERCENTILE_CONT (например, SQL Server, Oracle, BigQuery):

SELECT
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY value) AS median
FROM your_table;