STD

La función STD calcula la desviación estándar poblacional de un conjunto de valores numéricos. La desviación estándar mide cuánto se dispersan los valores respecto a la media: un valor bajo indica que los datos están agrupados cerca del promedio, mientras que un valor alto indica que están muy dispersos. Es una herramienta fundamental en análisis estadístico para entender la variabilidad de precios, tiempos de entrega, calificaciones o cualquier métrica numérica.

MySQL ofrece tres sinónimos para esta función: STD, STDDEV y STDDEV_POP. Los tres calculan exactamente lo mismo: la desviación estándar poblacional. Existe además STDDEV_SAMP, que calcula la desviación estándar muestral (con N-1 en el denominador), pero esa es una función diferente.

Sintaxis

STD(expresion)
STDDEV(expresion)
STDDEV_POP(expresion)

Las tres formas son equivalentes y devuelven la raíz cuadrada de la varianza poblacional. STD es la forma más corta, STDDEV es compatible con Oracle y STDDEV_POP es la más explícita sobre qué tipo de desviación estándar calcula.

La fórmula que aplica MySQL es:

STD = SQRT(SUM((x - media)^2) / N)

Donde x es cada valor, media es el promedio de todos los valores y N es el número de valores no nulos.

Comportamiento básico

Veamos la desviación estándar de los precios de todos los productos:

SELECT
    ROUND(AVG(precio), 2) AS precio_medio,
    ROUND(STD(precio), 2) AS desviacion_estandar,
    MIN(precio) AS precio_minimo,
    MAX(precio) AS precio_maximo
FROM productos;
precio_mediodesviacion_estandarprecio_minimoprecio_maximo
384.52428.679.991899.99

La desviación estándar de 428.67 es mayor que la media de 384.52, lo que indica una distribución muy dispersa. Esto tiene sentido: el catálogo incluye cables de 9.99 euros y portátiles de casi 1900 euros, una variabilidad enorme.

Para interpretar la desviación estándar, recuerda la regla empírica: en una distribución normal, aproximadamente el 68% de los valores caen dentro de una desviación estándar de la media, y el 95% dentro de dos desviaciones estándar.

Caso práctico: dispersión de precios por categoría

La desviación estándar te permite comparar la homogeneidad de precios entre categorías:

SELECT
    c.nombre AS categoria,
    COUNT(*) AS productos,
    ROUND(AVG(p.precio), 2) AS precio_medio,
    ROUND(STD(p.precio), 2) AS desviacion,
    ROUND(STD(p.precio) / AVG(p.precio) * 100, 1) AS coef_variacion
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
GROUP BY c.nombre
ORDER BY coef_variacion DESC;
categoriaproductosprecio_mediodesviacioncoef_variacion
Hogar5124.8098.5078.9
Deportes4189.99145.2076.4
Accesorios electrónicos742.8528.9067.4
Smartphones12785.42312.3039.8
Ropa mujer664.9938.5059.2
Ropa hombre659.9932.8054.7
Portátiles81245.50345.2027.7
Libros222.507.5033.3

La columna coef_variacion (coeficiente de variación) es clave: divide la desviación estándar entre la media y la expresa como porcentaje. Esto permite comparar categorías con rangos de precios muy diferentes. Hogar tiene la mayor variabilidad relativa (78.9%), mientras que Portátiles, a pesar de tener una desviación alta en valor absoluto (345.20), tiene la menor variabilidad relativa (27.7%) porque sus precios están relativamente agrupados alrededor de la media.

Caso práctico: detectar valores atípicos

La desviación estándar es la herramienta clásica para detectar outliers. Un producto cuyo precio está a más de 2 desviaciones estándar de la media de su categoría puede considerarse atípico:

SELECT
    p.nombre,
    c.nombre AS categoria,
    p.precio,
    stats.precio_medio,
    stats.desviacion,
    ROUND((p.precio - stats.precio_medio) / stats.desviacion, 2) AS z_score
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
JOIN (
    SELECT
        categoria_id,
        AVG(precio) AS precio_medio,
        STD(precio) AS desviacion
    FROM productos
    GROUP BY categoria_id
) stats ON p.categoria_id = stats.categoria_id
WHERE ABS(p.precio - stats.precio_medio) > 2 * stats.desviacion
ORDER BY ABS((p.precio - stats.precio_medio) / stats.desviacion) DESC;
nombrecategoriaprecioprecio_mediodesviacionz_score
ASUS ROG ZephyrusPortátiles1899.991245.50345.201.90

El z-score indica cuántas desviaciones estándar se aleja un valor de la media. Un z-score de 1.90 o superior sugiere un valor atípico. El ASUS ROG Zephyrus es el portátil más alejado de la media de su categoría, aunque con un z-score de 1.90 está justo en el borde del umbral.

Caso práctico: análisis de variabilidad en pedidos

Veamos la variabilidad del valor de los pedidos mes a mes:

SELECT
    DATE_FORMAT(fecha_pedido, '%Y-%m') AS mes,
    COUNT(*) AS num_pedidos,
    ROUND(AVG(total), 2) AS ticket_medio,
    ROUND(STD(total), 2) AS desviacion,
    ROUND(MIN(total), 2) AS pedido_minimo,
    ROUND(MAX(total), 2) AS pedido_maximo
FROM pedidos
WHERE estado = 'completado'
    AND YEAR(fecha_pedido) = 2025
GROUP BY DATE_FORMAT(fecha_pedido, '%Y-%m')
ORDER BY mes;
mesnum_pedidosticket_mediodesviacionpedido_minimopedido_maximo
2025-0120922.54385.20125.991899.99
2025-0223927.00412.5089.992145.00
2025-0327958.90356.80145.501945.00
2025-0421946.22398.4098.502050.00
2025-0525966.03378.90112.001890.00
2025-0630985.35345.60135.801975.00

Junio tiene la desviación más baja (345.60) a pesar de tener más pedidos, lo que significa que los montos de los pedidos fueron más uniformes. Febrero tuvo la mayor dispersión, con pedidos que van desde 89.99 hasta 2145 euros.

Manejo de NULL

STD ignora los valores NULL. Si todas las filas de un grupo tienen NULL, devuelve NULL. Si solo hay un valor no nulo, la desviación estándar es 0 (ya que no hay dispersión posible con un solo dato):

SELECT
    STD(precio) AS std_normal,
    COUNT(precio) AS valores_no_nulos
FROM productos
WHERE categoria_id = 5;

Si la categoría solo tiene un producto, la desviación será 0. Si no tiene productos o todos los precios son NULL, devolverá NULL.

Combinación con otras funciones

STD se combina bien con AVG para crear bandas de confianza:

SELECT
    c.nombre AS categoria,
    ROUND(AVG(p.precio), 2) AS media,
    ROUND(AVG(p.precio) - STD(p.precio), 2) AS banda_inferior,
    ROUND(AVG(p.precio) + STD(p.precio), 2) AS banda_superior
FROM productos p
JOIN categorias c ON p.categoria_id = c.id
GROUP BY c.nombre
HAVING COUNT(*) >= 3
ORDER BY media DESC;
categoriamediabanda_inferiorbanda_superior
Portátiles1245.50900.301590.70
Smartphones785.42473.121097.72
Deportes189.9944.79335.19
Hogar124.8026.30223.30

Las bandas inferior y superior representan el rango donde se espera encontrar la mayoría de los productos (aproximadamente el 68%). Cualquier producto fuera de este rango merece atención especial.

La diferencia entre STD (poblacional) y STDDEV_SAMP (muestral) es pequeña con muchos datos pero significativa con pocos. Si tus datos son una muestra de una población mayor (por ejemplo, encuestas de satisfacción de un subconjunto de clientes), usa STDDEV_SAMP. Si son la población completa (todos los productos del catálogo), usa STD.

En el siguiente artículo veremos VARIANCE para calcular la varianza.

Escrito por Eduardo Lázaro