CÓMO CALCULAR LA MEDIANA Y PERCENTILES EN MARIADB

En el análisis de datos y la ciencia de datos, la mediana y los percentiles son medidas de posición fundamentales. La mediana, percentil 50, es especialmente útil porque es robusta frente a valores atípicos, a diferencia de la media aritmética. Los percentiles permiten dividir un conjunto de datos en partes iguales y entender mejor su distribución, cuartiles, deciles, etc.. Afortunadamente, MariaDB, a partir de la versión 10.3.3, incluye de forma nativa funciones de ventana potentes para calcular estas métricas de manera eficiente y sin necesidad de procedimientos complejos ni código externo.

Funciones disponibles

MariaDB ofrece tres funciones principales relacionadas:

Función Tipo Descripción
"MEDIAN()" Ventana Calcula la mediana (percentil 50). Es un atajo de "PERCENTILE_CONT(0.5)".
"PERCENTILE_CONT()" Ventana (continua) Calcula un percentil continuo. Interpola entre valores cuando es necesario.
"PERCENTILE_DISC()" Ventana (discreta) Calcula un percentil discreto. Devuelve siempre un valor real existente en los datos.

Estas funciones son window functions, o funciones de ventana, por lo que devuelven un valor por cada fila del resultado, no colapsan las filas como un GROUP BY tradicional.

Sintaxis básica

MEDIAN

MEDIAN (expresión) OVER (
  [PARTITION BY expresión_partición]
)

PERCENTILE_CONT y PERCENTILE_DISC

PERCENTILE_CONT(p) WITHIN GROUP (ORDER BY expresión)
  OVER ([PARTITION BY expresión_partición])

PERCENTILE_DISC(p) WITHIN GROUP (ORDER BY expresión)
  OVER ([PARTITION BY expresión_partición])
Donde "p" es un valor entre 0 y 1, por ejemplo: 0.25 para el percentil 25, 0.5 para la mediana, 0.75 para el percentil 75.

Ejemplo práctico

Ejemplo de valoraciones de libros:

REATE TABLE book_rating (
  name CHAR(30),
  star_rating TINYINT
);

INSERT INTO book_rating VALUES 
  ('Lord of the Ladybirds', 5),
  ('Lord of the Ladybirds', 3),
  ('Lady of the Flies', 1),
  ('Lady of the Flies', 2),
  ('Lady of the Flies', 5);

Calcular la mediana por libro

SELECT 
  name,
  MEDIAN(star_rating) OVER (PARTITION BY name) AS mediana
FROM book_rating;

//Resultado
+-----------------------+------------+
| name| mediana|
+-----------------------+------------+
| Lord of the Ladybirds | 4.000000|
| Lord of the Ladybirds | 4.000000|
| Lady of the Flies | 2.000000|
| Lady of the Flies | 2.000000|
| Lady of the Flies | 2.000000|
+-----------------------+------------+

Percentiles continuos, PERCENTILE_CONT

SELECT 
  name,
  PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY star_rating) 
OVER (PARTITION BY name) AS p25,
  PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY star_rating) 
OVER (PARTITION BY name) AS mediana,
  PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY star_rating) 
OVER (PARTITION BY name) AS p75
FROM book_rating;
"PERCENTILE_CONT" interpola cuando el percentil cae entre dos valores.

Percentiles discretos, PERCENTILE_DISC

SELECT 
  name,
  PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY star_rating) 
OVER (PARTITION BY name) AS mediana_discreta
FROM book_rating;
En este caso, para “Lord of the Ladybirds” devuelve 3, un valor real de los datos, mientras que "PERCENTILE_CONT devolvía 4, promedio interpolado.

Cómo obtener una sola fila por grupo

Como son funciones de ventana, se repite el valor en todas las filas del partición. Para obtener un resultado agregado, una fila por grupo, puedes usar cualquiera de estas técnicas:

Opción 1 – DISTINCT

SELECT DISTINCT
  name,
  MEDIAN(star_rating) OVER (PARTITION BY name) AS mediana
FROM book_rating;

Opción 2 – MAX + subquery (muy común)

SELECT 
  name,
  MAX(mediana) AS mediana,
  MAX(p25) AS percentil_25,
  MAX(p75) AS percentil_75
FROM (
  SELECT 
name,
MEDIAN(star_rating) OVER (PARTITION BY name) AS mediana,
PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS p25,
PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS p75
  FROM book_rating
) t
GROUP BY name;

Diferencias importantes entre CONT y DISC

  • "PERCENTILE_CONT" (continua): Interpola. Ideal cuando los datos son numéricos continuos y quieres una estimación suave.
  • "PERCENTILE_DISC" (discreta): Devuelve siempre un valor real del conjunto. Preferible cuando los datos son discretos o quieres un valor existente.

Casos de uso frecuentes en ciencia de datos

  • Cálculo de mediana de salarios, tiempos de respuesta o importes de venta, robusto a outliers.
  • Definición de rangos intercuartílicos (IQR = P75 – P25) para detección de outliers.
  • Segmentación de clientes por percentiles de gasto o frecuencia.
  • Creación de features para modelos de Machine Learning, variables de ranking o posición relativa.

Notas adicionales

  • Las funciones están disponibles desde MariaDB 10.3.3.
  • En MariaDB ColumnStore también existen implementaciones distribuidas y la posibilidad de crear UDFs de agregación personalizadas (incluido un ejemplo oficial de median).
  • Los valores NULL se ignoran en el cálculo.
  • El rendimiento es bueno gracias a que se ejecutan como operaciones de ventana optimizadas.