NULL en agregaciones y JOINs
Cómo se comporta NULL en COUNT, SUM y JOINs
NULL en agregaciones y JOINs es una lección gratuita de SQL Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de SQL Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de SQL Academy incluye 4 lecciones en total.
Los NULL cambian los cálculos
Las funciones de agregación y los JOIN tratan los NULL de formas especiales. Si no conoce las reglas, sus totales y conteos pueden ser incorrectos sin que resulte evidente.
Esta lección muestra cómo interactúan COUNT, SUM, AVG, GROUP BY y los JOIN externos con los valores ausentes.
SELECT amount FROM payments;
-- amount
-- -------
-- 100
-- NULL <- missing
-- 200Las funciones de agregación ignoran los NULL
La mayoría de las funciones de agregación — SUM, AVG, MIN, MAX — simplemente omiten los valores NULL. Solo agregan las filas que contienen datos.
Por tanto, un importe NULL no afecta a SUM; simplemente queda fuera del total.
-- Using amounts 100, NULL, 200
SELECT
SUM(amount) AS total, -- 300 (NULL skipped)
MIN(amount) AS lo, -- 100
MAX(amount) AS hi -- 200
FROM payments;AVG también omite los NULL
AVG divide la suma de los valores que no son NULL entre el número de valores que no son NULL. Los NULL se excluyen de ambos cálculos.
Esto es importante: un promedio de {100, NULL, 200} es 150, no 100 — el NULL no se cuenta como cero.
-- (100 + 200) / 2 = 150, the NULL row is ignored
SELECT AVG(amount) AS avg_amount FROM payments;
-- If you WANT NULLs counted as 0, COALESCE first:
SELECT AVG(COALESCE(amount, 0)) AS avg_with_zeros FROM payments; -- 100COUNT(*) frente a COUNT(column)
Esta distinción confunde a muchas personas:
COUNT(*)cuenta las filas, incluidas las que contienen NULL.COUNT(column)cuenta solo las filas en las que esa columna no es NULL.
-- 3 rows total, but only 2 have a non-NULL amount
SELECT
COUNT(*) AS row_count, -- 3
COUNT(amount) AS has_amount -- 2
FROM payments;COUNT(DISTINCT) y NULL
COUNT(DISTINCT col) cuenta el número de valores distintos que no son NULL. Los NULL se excluyen por completo — nunca incrementan el recuento de valores distintos.
Téngalo en cuenta al medir «cuántos X únicos».
-- statuses: 'paid', NULL, 'paid', 'void'
SELECT COUNT(DISTINCT status) AS distinct_statuses
FROM payments;
-- 2 (paid, void) -- NULL not countedAgregaciones sobre conjuntos vacíos
Cuando una función de agregación se aplica a cero filas, el resultado depende de la función:
COUNT(...)devuelve0.SUM,AVG,MINyMAXdevuelvenNULL.
Utilice COALESCE para convertir una suma NULL en 0 cuando corresponda.
-- No rows match -> SUM is NULL, not 0
SELECT COALESCE(SUM(amount), 0) AS total
FROM payments
WHERE status = 'refunded'; -- no such rowsGROUP BY agrupa los NULL
Aunque NULL = NULL es desconocido en otros contextos, GROUP BY coloca todos los NULL en un único grupo.
Así, una categoría NULL se convierte en su propio grupo en los resultados, lo que permite resumir juntas las filas con datos ausentes.
SELECT category, COUNT(*) AS n
FROM products
GROUP BY category;
-- category | n
-- ---------+---
-- books | 5
-- toys | 3
-- NULL | 2 <- all NULL categories in one groupNULL generados por JOIN externos
Los JOIN externos son una fuente importante de NULL. Un LEFT JOIN conserva cada fila de la izquierda; cuando no hay coincidencia a la derecha, las columnas del lado derecho se convierten en NULL.
Esos NULL significan «no hay ninguna fila coincidente», no «un valor NULL almacenado».
SELECT c.name, o.id AS order_id
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;
-- name | order_id
-- ------+---------
-- Alice | 10
-- Bob | NULL <- Bob has no ordersConteo de coincidencias tras un LEFT JOIN
Para contar solo las coincidencias reales después de un LEFT JOIN, cuente una columna de la tabla derecha que no sea NULL, no COUNT(*).
COUNT(o.id) ignora las filas con NULL generadas por las filas izquierdas sin coincidencia, por lo que proporciona el número real de pedidos.
SELECT c.name, COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
-- Bob shows 0, not 1×NULLFiltrado de las no coincidencias
Un detalle importante: colocar una condición sobre la tabla derecha en WHERE después de un LEFT JOIN lo convierte en un INNER JOIN, porque NULL = value es desconocido y se filtra.
Si desea conservar las filas sin coincidencia, coloque la condición en la cláusula ON o compruebe explícitamente si es NULL.
-- Accidentally drops Bob (his o.status is NULL)
SELECT c.name FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.status = 'open';
-- Keep unmatched rows: move the test into ON
SELECT c.name FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id AND o.status = 'open';Reglas prácticas
Conserve estas reglas para todas las consultas que combinen agregaciones y JOIN:
- Las funciones de agregación ignoran los NULL, excepto
COUNT(*). COUNT(col)<COUNT(*)cuando col contiene NULL.- Una
SUMoAVGsobre un conjunto vacío es NULL — envuélvala enCOALESCE. - LEFT JOIN genera NULL para las no coincidencias; cuente una clave del lado derecho.
- Los filtros de la tabla derecha deben ir en
ON, no enWHERE.
SELECT c.name,
COALESCE(SUM(o.amount), 0) AS spent,
COUNT(o.id) AS orders
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;Comprobación rápida
Una columna amount contiene los valores 100, NULL y 200 en tres filas. ¿Qué devuelven COUNT(*) y COUNT(amount)?
Recapitulación
Ha aprendido cómo se propagan los NULL por las agregaciones y los JOIN: las funciones de agregación omiten los NULL, COUNT(*) cuenta filas mientras que COUNT(col) cuenta valores que no son NULL, las sumas de conjuntos vacíos son NULL y GROUP BY agrupa todos los NULL en un único grupo.
También ha visto que los JOIN externos generan NULL para las no coincidencias y por qué los filtros de la tabla derecha deben ir en ON. Con esto completa el curso Working with NULLs — ahora puede manejar los datos ausentes con confianza.
-- A NULL-safe summary query
SELECT c.name,
COUNT(o.id) AS orders,
COALESCE(SUM(o.amount), 0) AS total_spent
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name
ORDER BY total_spent DESC;Preguntas frecuentes
¿La lección «NULL en agregaciones y JOINs» es gratis?
Sí — el texto completo de «NULL en agregaciones y JOINs» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de SQL Academy, actualiza a CoddyKit PRO. El curso de SQL Academy incluye 4 lecciones en total.
¿Qué aprenderé en «NULL en agregaciones y JOINs»?
Cómo se comporta NULL en COUNT, SUM y JOINs Practicas SQL Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar SQL Academy?
No se requiere experiencia previa. SQL Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «NULL en agregaciones y JOINs»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de SQL Academy?
Sí. Cada lección de SQL Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Qué significa realmente NULL
- IS NULL e IS NOT NULL
- COALESCE y NULLIF
- NULL en agregaciones y JOINs