AVG y valores NULL en SQL

Por el equipo de promedio.net · Actualizado el

AVG ignora los valores NULL: suma solo los valores presentes y divide entre cuántos son, no entre el total de filas. Si un NULL debe contar como cero (una tarea no entregada, un día sin ventas), conviértelo antes de promediar con AVG(COALESCE(columna, 0)). Y si todos los valores son NULL, AVG devuelve NULL.

Sintaxis

AVG(columna)                 -- ignora NULL: SUM(columna) / COUNT(columna)
AVG(COALESCE(columna, 0))    -- NULL cuenta como 0: divide entre todas las filas
COALESCE(AVG(columna), 0)    -- si no hay ningún valor, muestra 0 en vez de NULL
AVG(NULLIF(columna, 0))      -- trata los 0 como NULL: los excluye

Fíjate en el orden de COALESCE y AVG en las líneas 2 y 3: no hacen lo mismo. ISNULL(columna, 0) en SQL Server e IFNULL(columna, 0) en MySQL y SQLite equivalen a COALESCE con dos argumentos; COALESCE es estándar y funciona en todos.

Paso a paso

  1. Averigua qué significa un NULL en tu tabla: ¿dato desconocido o valor cero?
  2. Si es desconocido (una encuesta sin respuesta, un sensor caído), deja que AVG lo ignore.
  3. Si es cero (no entregó, no vendió), usa AVG(COALESCE(columna, 0)).
  4. Muestra COUNT(columna) junto al promedio para saber cuántos valores reales lo respaldan.

Tabla de ejemplo: tareas de tres alumnos, con NULL en las que no se entregaron.

CREATE TABLE entregas (
  alumno VARCHAR(30),
  tarea  INT,
  puntos DECIMAL(4, 1)   -- NULL = no la entregó
);
INSERT INTO entregas VALUES
  ('Iris', 1, 9.0), ('Iris', 2, 8.0), ('Iris', 3, NULL), ('Iris', 4, 10.0),
  ('Omar', 1, 7.0), ('Omar', 2, NULL), ('Omar', 3, NULL), ('Omar', 4, 8.0),
  ('Rosa', 1, 6.0), ('Rosa', 2, 7.5), ('Rosa', 3, 8.5),  ('Rosa', 4, 9.0);

Ejemplos resueltos

Ejemplo 1: dos formas de calificar las tareas

SELECT alumno,
       AVG(puntos)              AS prom_entregadas,
       AVG(COALESCE(puntos, 0)) AS prom_con_ceros,
       COUNT(*)                 AS tareas,
       COUNT(puntos)            AS entregadas
FROM entregas
GROUP BY alumno;
alumnoprom_entregadasprom_con_cerostareasentregadas
Iris9.06.7543
Omar7.53.7542
Rosa7.757.7544

Omar entregó 2 de 4 tareas con 7 y 8. Si solo cuentan las entregadas, su promedio es 7.5 y supera a Rosa, que entregó todas. Si las no entregadas valen 0, baja a 3.75. Ninguna consulta es la «correcta»: depende de la regla del curso, pero la segunda es la que suele aplicarse a tareas. COUNT(*) cuenta filas; COUNT(puntos), solo las que tienen valor.

Ejemplo 2: SUM / COUNT(*) no es AVG

SELECT ROUND(AVG(puntos), 2)              AS con_avg,
       ROUND(SUM(puntos) / COUNT(puntos), 2) AS suma_entre_valores,
       ROUND(SUM(puntos) / COUNT(*), 2)      AS suma_entre_filas
FROM entregas;
con_avgsuma_entre_valoressuma_entre_filas
8.118.116.08

Los 9 valores presentes suman 73.0. AVG divide entre 9 (8.11), igual que SUM / COUNT(puntos). Dividir entre COUNT(*), las 12 filas, equivale a contar los NULL como cero (6.08). Si reescribes un AVG a mano, este cambio pasa desapercibido. Cuidado también con la división entera: si puntos fuera INT, SUM / COUNT truncaría en PostgreSQL, SQL Server y SQLite; ver AVG con enteros.

Ejemplo 3: ningún valor presente

SELECT AVG(puntos)              AS sin_coalesce,
       COALESCE(AVG(puntos), 0) AS con_coalesce
FROM entregas
WHERE alumno = 'Omar' AND tarea IN (2, 3);
sin_coalescecon_coalesce
NULL0

Las dos tareas filtradas son NULL, así que AVG no tiene nada que promediar y devuelve NULL; lo mismo pasa si el WHERE no deja ninguna fila. COALESCE por fuera solo cambia lo que se muestra. Si tu aplicación hace cálculos con ese 0, asegúrate de que «sin datos» y «promedio cero» no se confundan.

Excluir ceros como si fueran NULL

A veces el problema es el contrario: el sistema guarda 0 cuando no hay dato. AVG(NULLIF(puntos, 0)) convierte cada 0 en NULL y lo deja fuera, igual que PROMEDIO.SI(rango;"<>0") en Excel. Úsalo solo si un 0 real es imposible.

Errores comunes

En Python, el equivalente es skipna de pandas, explicado en ignorar NaN en Python.

Fuentes

  1. PostgreSQL, funciones de agregado. Los agregados distintos de count(*) ignoran NULL y devuelven NULL sin filas. Consultado el 11 de noviembre de 2026.