CodeGym /Cursos /SQL SELF /Influencia de NULL en funciones agregadas: SUM(), COUNT()...

Influencia de NULL en funciones agregadas: SUM(), COUNT(), AVG(), MIN(), MAX()

SQL SELF
Nivel 9 , Lección 2
Disponible

Recuerda que las funciones agregadas son aquellas que trabajan con varias filas de datos a la vez y devuelven un solo resultado. En PostgreSQL vas a usar muy a menudo las siguientes funciones agregadas:

  • SUM() — suma de datos.
  • AVG() — cálculo del valor promedio.
  • MIN() — búsqueda del valor mínimo.
  • MAX() — búsqueda del valor máximo.
  • COUNT() — conteo de filas.

A primera vista, todo es fácil: le pasas una columna o una expresión a la función y obtienes el resultado. Pero, ¿qué pasa si en la columna aparece un NULL?

Comportamiento de NULL en agregados: resumen rápido

Aquí es donde empieza lo interesante:

  • SUM() y AVG() ignoran NULL. Si al menos un registro tiene valor NULL, simplemente no se tiene en cuenta en los cálculos. Tiene sentido, ¿no? ¿Cómo va a crecer la suma si alguien "no vino a la fiesta"? ¿O cómo calcular el promedio si falta un valor?
  • MIN() y MAX() también saltan los NULL. Encuentran el valor mínimo o máximo solo entre los datos que no son NULL. Así que, si buscas el empleado más joven y alguien no rellenó la fecha de nacimiento, NULL no va a ganar.
  • COUNT(*) cuenta todas las filas, incluso las que tienen NULL. Pero COUNT(column) solo cuenta las filas donde la columna indicada tiene valor, o sea, NULL se ignora.

Vamos a verlo con ejemplos.

Ejemplos de uso de funciones agregadas con NULL

Aquí tienes la tabla students_scores, que contiene las notas de los estudiantes en un test:

student_id name score
1 Alicia 85
2 Bob NULL
3 Charlie 92
4 Dana NULL
5 Elena 74

Ahora vamos a lanzar unas consultas y analizar sus resultados:

  1. Suma de todas las notas: SUM()
SELECT SUM(score) AS total_score
FROM students_scores;

Resultado:

total_score
251

Como ves, los valores NULL simplemente no participaron en la suma. Para Alicia (85), Charlie (92) y Elena (74) la suma es 251. Bob y Dana se quedaron fuera.

  1. Nota promedio: AVG()
SELECT AVG(score) AS average_score
FROM students_scores;

Resultado:

average_score
83.67

Otra vez, los NULL fueron ignorados y el promedio se calculó solo para quienes tienen nota: (85 + 92 + 74) / 3 = 83.67.

  1. Nota mínima y máxima: MIN() y MAX()
SELECT
    MIN(score) AS min_score, 
    MAX(score) AS max_score 
FROM students_scores;

Resultado:

min_score max_score
74 92

Aquí también es fácil: los valores NULL otra vez se ignoran, y la nota mínima es 74 y la máxima es 92.

  1. Conteo de filas: COUNT(*) vs COUNT(column)
SELECT
    COUNT(*) AS total_rows, 
    COUNT(score) AS non_null_scores 
FROM students_scores;

Resultado:

total_rows non_null_scores
5 3
  • COUNT(*) contó todas las filas, incluso donde score es NULL.
  • COUNT(score) solo contó las filas donde la columna score tiene valor.

Casos prácticos

Vamos con algunos ejemplos prácticos.

Ejemplo 1: Contar empleados con y sin salario indicado

Supón que tienes una tabla employees con los salarios.

id name salary
1 Alex Lin 50000
2 Maria Chi NULL
3 Anna Song 60000
4 Otto Art NULL
5 Liam Park 55000

Queremos saber cuántos empleados han indicado su salario y cuántos no.

SELECT
    COUNT(*) AS total_employees,
    COUNT(salary) AS employees_with_salary,
    COUNT(*) - COUNT(salary) AS employees_without_salary
FROM employees;

Aquí:

  • COUNT(*) devuelve el número total de empleados.
  • COUNT(salary) cuenta cuántos empleados han indicado su salario.
  • Para saber cuántos no lo han hecho, solo restamos un valor al otro.

Resultado

total_employees employees_with_salary employees_without_salary
5 3 2

Ejemplo 2: Calcular el precio promedio de productos con datos faltantes

Eres dueño de una tienda mágica y en la tabla products hay una columna price, pero algunos productos aún no tienen precio.

id name price
1 Magic Wand 150
2 Enchanted Cloak NULL
3 Potion Bottle 75
4 Spell Book 200
5 Crystal Ball NULL

Necesitas saber el precio promedio solo para los productos que sí tienen precio.

SELECT AVG(price) AS average_price
FROM products;

Resultado:

average_price
141.6667

Si quieres poner un precio por defecto para los productos sin precio (por ejemplo, ponerlo a 0), puedes usar la función COALESCE() que veremos en la próxima lección.

Ejemplo 3: Encontrar la edad mínima y máxima de los estudiantes

En la tabla students se guarda la edad de los alumnos, pero para algunos no se conoce la edad (NULL).

id name age
1 Alex Lin 20
2 Maria Chi NULL
3 Anna Song 19
4 Otto Art 22
5 Liam Park NULL

Queremos saber quién es el estudiante más joven y el mayor.

SELECT
    MIN(age) AS youngest_student,
    MAX(age) AS eldest_student
FROM students;

Resultado:

youngest_student eldest_student
19 22

Esta consulta devuelve la edad mínima y máxima solo para los estudiantes que sí tienen edad indicada. NULL otra vez se ignora.

Detalles y trampas

Cuando trabajes con NULL en agregados, es importante recordar lo siguiente:

  • En la suma SUM() y el promedio AVG(), los NULL no se tienen en cuenta. Puedes usar esto para no meter valores "vacíos" en los cálculos.
  • Si necesitas contar filas con NULL en la columna, usa COUNT(*).
  • Al usar MIN() o MAX(), NULL no afecta el resultado. Pero si toda la columna es solo NULL, el resultado también será NULL.

Consejos para trabajar con NULL

  1. Ten en cuenta el contexto de tu consulta. Es importante entender si necesitas tener en cuenta los NULL en tu consulta. A veces, como con AVG(), ignorarlos es justo lo que quieres. Otras veces, como al contar el total, es importante incluir también las filas con NULL.
  2. Usa COALESCE() si hace falta. Si necesitas reemplazar NULL por un valor por defecto en los cálculos, la función COALESCE() será tu aliada (pero eso lo veremos en la próxima lección).
  3. No confundas COUNT(*) y COUNT(column). Este es un error clásico de principiantes. El primero cuenta filas, el segundo solo filas con valores no nulos.

Ahora ya sabes cómo el silencioso NULL puede afectar a los agregados. Este conocimiento te ayudará a evitar sorpresas y a usar NULL a tu favor. En la próxima lección veremos la potente función COALESCE() para manejar NULL aún mejor.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION