NTILE EN MYSQL: QUÉ ES, CÓMO FUNCIONA Y EJEMPLOS PRÁCTICOS

NTILE es una función ventana, disponible en MySQL desde la versión 8.0. Su propósito es dividir un conjunto de filas ordenadas en un número determinado de grupos lo más iguales posible y asignar a cada fila un número de grupo (del 1 al n).Es especialmente útil para:
  • Agrupar la muestra en intervalos estadísticos proporcionales.
  • Segmentar datos por ejemplo, clientes en “top 25 %”, “medio-alto”, etc..
  • Distribuir trabajo o recursos de forma equilibrada.

Sintaxis

NTILE(n) OVER (
    [PARTITION BY columna1, columna2, ...]
    ORDER BY columna_orden [ASC|DESC]
)
  • "n": número entero positivo que indica en cuántos grupos quieres dividir las filas.
  • "PARTITION BY": Es opcional y divide el conjunto de resultados en particiones independientes. NTILE se aplica dentro de cada partición.
  • "ORDER BY": obligatorio en la práctica. Determina el orden en el que se asignan los grupos.

Cómo reparte los grupos MySQL

MySQL intenta que los grupos tengan el mismo tamaño. Si el número total de filas no es divisible exactamente por "n":, los primeros grupos reciben una fila extra.

Ejemplo

  • 10 filas y "NTILE(3)": grupos de 4, 3 y 3 filas.
  • 11 filas y "NTILE(4)": grupos de 3, 3, 3 y 2 filas.

Ejemplo básico

Tabla ventas:

CREATE TABLE ventas (
    id INT PRIMARY KEY,
    vendedor VARCHAR(50),
    importe DECIMAL(10,2)
);

INSERT INTO ventas VALUES
(1, 'Ana', 1200),
(2, 'Luis', 850),
(3, 'María', 2100),
(4, 'Pedro', 950),
(5, 'Ana', 1800),
(6, 'Luis', 1100),
(7, 'María', 700),
(8, 'Pedro', 1500),
(9, 'Ana', 900),
(10,'Luis', 1300);
Se consultan los 4 cuartiles de ventas ordenadas por importe:

SELECT 
    id,
    vendedor,
    importe,
    NTILE(4) OVER (ORDER BY importe DESC) AS cuartil
FROM ventas
ORDER BY importe DESC;

Resultado aproximado

id vendedor importe cuartil
3 María 2100 1
5 Ana 1800 1
8 Pedro 1500 2
10 Luis 1300 2
1 Ana 1200 3
6 Luis 1100 3
4 Pedro 950 4
9 Ana 900 4
2 Luis 850 4
7 María 700 4

Los tamaños exactos de los grupos pueden variar ligeramente según la distribución, pero el principio se mantiene.

Ejemplo con "PARTITION BY"

Si se quiere calcular el cuartil, cada uno de los tres valores que dividen un conjunto de datos ordenados en cuatro partes iguales, dentro de cada vendedor:

SELECT 
    id,
    vendedor,
    importe,
    NTILE(3) OVER (
        PARTITION BY vendedor 
        ORDER BY importe DESC
    ) AS tercil_por_vendedor
FROM ventas
ORDER BY vendedor, importe DESC;
Así cada vendedor tiene sus propias tres divisiones independientes.

Casos de uso comunes

  • Análisis de rendimiento
  • Identificar el top 20 % de productos, empleados o clientes, "NTILE(5)".
  • Segmentación de clientes (RFM, scoring, etc.)
  • Dividir la base de clientes en quintiles según frecuencia de compra o valor monetario.
  • Distribución equitativa
  • Asignar filas a n buckets para procesamiento paralelo o A/B testing.
  • Creación de rankings visuales
  • Mostrar “oro / plata / bronce” o niveles de servicio.

Consideraciones importantes

  • Requiere MySQL 8.0 o superior, las funciones de ventana no existían en versiones anteriores.
  • El rendimiento es bueno en la mayoría de los casos, pero un "ORDER BY" costoso sobre grandes volúmenes de datos puede beneficiarse de índices adecuados.
  • NTILE no es determinista cuando hay empates en la columna de ordenación. Si se necesita un comportamiento predecible, añade una columna secundaria al "ORDER BY"
  • No se puede usar directamente en la cláusula "WHERE" . Si se quiere filtrar por el número de grupo, es necesario envolver la consulta en una subconsulta o CTE:

    WITH ranking AS (
        SELECT *, NTILE(4) OVER (ORDER BY importe DESC) AS cuartil
        FROM ventas
    )
    SELECT * FROM ranking WHERE cuartil = 1;