La varianza mide cuanto se dispersan los valores alrededor de su media: cuanto mayor es, mas "ancha" es la distribucion de los datos. Es la media de las desviaciones al cuadrado respecto a la media, expresada en las unidades de entrada al cuadrado. SQL ofrece dos variantes, la muestral VAR_SAMP y la poblacional VAR_POP, y la diferencia importa mas de lo que parece.
Dos funciones y un atajo
PostgreSQL expone tres nombres, pero detras solo hay dos formulas:
VAR_POP(x) es la varianza poblacional: divide la suma de desviaciones al cuadrado entre N.
VAR_SAMP(x) es la varianza muestral: divide entre N - 1 (correccion de Bessel).
VARIANCE(x) es simplemente un alias de VAR_SAMP.
SELECT
var_samp(amount) AS sample_variance,
var_pop(amount) AS pop_variance,
variance(amount) AS bare_variance
FROM orders;
Conclusion clave: en PostgreSQL, el VARIANCE a secas NO es una opcion "neutral", divide entre N - 1. En ClickHouse las funciones explicitas se llaman varSamp y varPop. MySQL es la trampa: alli VARIANCE es un sinonimo de VAR_POP (division entre N), no de VAR_SAMP. Por eso una consulta con VARIANCE a secas devuelve numeros distintos en PostgreSQL y en MySQL para los mismos datos. Para codigo portable, escribe siempre de forma explicita la version que necesitas.
Muestra o poblacion
Cual necesitas depende de lo que representen tus filas.
- Si las filas son TODOS los objetos que te interesan (por ejemplo, todos los pedidos de un dia concreto), usa
VAR_POP.
- Si las filas son una muestra de un conjunto mayor no observado (pedidos como muestra del comportamiento general de los clientes), usa
VAR_SAMP.
SELECT
status,
count(*) AS n,
round(var_samp(amount)::numeric, 2) AS variance
FROM orders
GROUP BY status
ORDER BY variance DESC NULLS LAST;
Con N grande, la diferencia entre dividir entre N y entre N - 1 desaparece. En grupos pequenos se nota: con N = 2, la varianza muestral es exactamente el doble de la poblacional. Por eso, en segmentos dispersos o con muchos grupos pequenos, la eleccion de la funcion mueve directamente los numeros del informe y conviene hacerla explicita en lugar de confiar en un valor por defecto. Cuando dudes si tus filas son una poblacion completa o una muestra, tratarlas como muestra y usar VAR_SAMP suele ser lo mas seguro: da una estimacion no sesgada de la dispersion, mientras que VAR_POP sobre una muestra la subestima de forma sistematica.
La varianza es la desviacion estandar al cuadrado
Varianza y desviacion estandar son dos caras del mismo numero: STDDEV es la raiz cuadrada de VARIANCE. STDDEV_SAMP se corresponde con VAR_SAMP y STDDEV_POP con VAR_POP. Esa identidad es util para comprobaciones y para cambiar de unidades.
SELECT
var_samp(salary) AS variance_salary,
stddev_samp(salary) AS stddev_salary,
sqrt(var_samp(salary)) AS stddev_via_sqrt
FROM employees;
La desviacion estandar esta en las mismas unidades que los datos (dolares, euros), mientras que la varianza esta en esas unidades al cuadrado. Por eso los informes casi siempre muestran STDDEV a las personas y reservan la varianza para los calculos internos, donde el cuadrado resulta comodo (por ejemplo, al sumar las varianzas de variables independientes).
Detalles numericos y trampas
- Los
NULL se ignoran en silencio: VAR_SAMP solo cuenta los valores no nulos, y N es ese recuento, no el total de filas.
- En una sola fila,
VAR_SAMP devuelve NULL (no puedes dividir entre N - 1 = 0), mientras que VAR_POP devuelve 0. Esta es la trampa clasica al agrupar: los grupos de una sola fila producen NULL de repente.
SELECT
dept,
count(*) AS n,
var_samp(salary) AS vs,
var_pop(salary) AS vp
FROM employees
GROUP BY dept;
- El tipo de resultado es
double precision para entradas float y numeric para entradas enteras y numeric. Con numeros muy grandes la ruta float puede perder precision; convierte a numeric cuando necesites estabilidad.
- No calcules la varianza sobre promedios ya agregados, da un resultado erroneo. La varianza se toma sobre los valores originales sin agregar.
SELECT var_samp(amount::numeric) AS stable_variance
FROM orders
WHERE status = 'paid';
Regla corta: en PostgreSQL usa VAR_SAMP (o VARIANCE) para muestras, VAR_POP para una poblacion completa, vigila los NULL en grupos de una sola fila y pasa a STDDEV mediante la raiz cuadrada cuando quieras unidades legibles. Y recuerda que en MySQL VARIANCE significa VAR_POP.
La varianza mide cuanto se dispersan los valores alrededor de su media: cuanto mayor es, mas "ancha" es la distribucion de los datos. Es la media de las desviaciones al cuadrado respecto a la media, expresada en las unidades de entrada al cuadrado. SQL ofrece dos variantes, la muestral
VAR_SAMPy la poblacionalVAR_POP, y la diferencia importa mas de lo que parece.Dos funciones y un atajo
PostgreSQL expone tres nombres, pero detras solo hay dos formulas:
VAR_POP(x)es la varianza poblacional: divide la suma de desviaciones al cuadrado entreN.VAR_SAMP(x)es la varianza muestral: divide entreN - 1(correccion de Bessel).VARIANCE(x)es simplemente un alias deVAR_SAMP.SELECT var_samp(amount) AS sample_variance, var_pop(amount) AS pop_variance, variance(amount) AS bare_variance -- equals var_samp FROM orders;Conclusion clave: en PostgreSQL, el
VARIANCEa secas NO es una opcion "neutral", divide entreN - 1. En ClickHouse las funciones explicitas se llamanvarSampyvarPop. MySQL es la trampa: alliVARIANCEes un sinonimo deVAR_POP(division entreN), no deVAR_SAMP. Por eso una consulta conVARIANCEa secas devuelve numeros distintos en PostgreSQL y en MySQL para los mismos datos. Para codigo portable, escribe siempre de forma explicita la version que necesitas.Muestra o poblacion
Cual necesitas depende de lo que representen tus filas.
VAR_POP.VAR_SAMP.-- Spread of order amounts per status, treating each group as a sample SELECT status, count(*) AS n, round(var_samp(amount)::numeric, 2) AS variance FROM orders GROUP BY status ORDER BY variance DESC NULLS LAST;Con
Ngrande, la diferencia entre dividir entreNy entreN - 1desaparece. En grupos pequenos se nota: conN = 2, la varianza muestral es exactamente el doble de la poblacional. Por eso, en segmentos dispersos o con muchos grupos pequenos, la eleccion de la funcion mueve directamente los numeros del informe y conviene hacerla explicita en lugar de confiar en un valor por defecto. Cuando dudes si tus filas son una poblacion completa o una muestra, tratarlas como muestra y usarVAR_SAMPsuele ser lo mas seguro: da una estimacion no sesgada de la dispersion, mientras queVAR_POPsobre una muestra la subestima de forma sistematica.La varianza es la desviacion estandar al cuadrado
Varianza y desviacion estandar son dos caras del mismo numero:
STDDEVes la raiz cuadrada deVARIANCE.STDDEV_SAMPse corresponde conVAR_SAMPySTDDEV_POPconVAR_POP. Esa identidad es util para comprobaciones y para cambiar de unidades.SELECT var_samp(salary) AS variance_salary, stddev_samp(salary) AS stddev_salary, sqrt(var_samp(salary)) AS stddev_via_sqrt -- matches stddev_samp FROM employees;La desviacion estandar esta en las mismas unidades que los datos (dolares, euros), mientras que la varianza esta en esas unidades al cuadrado. Por eso los informes casi siempre muestran
STDDEVa las personas y reservan la varianza para los calculos internos, donde el cuadrado resulta comodo (por ejemplo, al sumar las varianzas de variables independientes).Detalles numericos y trampas
NULLse ignoran en silencio:VAR_SAMPsolo cuenta los valores no nulos, yNes ese recuento, no el total de filas.VAR_SAMPdevuelveNULL(no puedes dividir entreN - 1 = 0), mientras queVAR_POPdevuelve0. Esta es la trampa clasica al agrupar: los grupos de una sola fila producenNULLde repente.-- Single-row group: var_samp is NULL, var_pop is 0 SELECT dept, count(*) AS n, var_samp(salary) AS vs, -- NULL when n = 1 var_pop(salary) AS vp -- 0 when n = 1 FROM employees GROUP BY dept;double precisionpara entradas float ynumericpara entradas enteras ynumeric. Con numeros muy grandes la ruta float puede perder precision; convierte anumericcuando necesites estabilidad.-- Cast to numeric for stable variance on large monetary values SELECT var_samp(amount::numeric) AS stable_variance FROM orders WHERE status = 'paid';Regla corta: en PostgreSQL usa
VAR_SAMP(oVARIANCE) para muestras,VAR_POPpara una poblacion completa, vigila losNULLen grupos de una sola fila y pasa aSTDDEVmediante la raiz cuadrada cuando quieras unidades legibles. Y recuerda que en MySQLVARIANCEsignificaVAR_POP.