Imagina que unes dos tablas: students (estudiantes) y enrollments (inscripciones a cursos). Si en la tabla enrollments no hay info sobre algún estudiante, pero usas, por ejemplo, un LEFT JOIN, las filas de la tabla students igual van a aparecer, pero la info de enrollments va a faltar. En vez de datos concretos, en esos casos aparece NULL.
Más o menos así se ve:
Tabla students:
| id | name |
|---|---|
| 1 | Eva |
| 2 | Peter |
| 3 | Anna |
Tabla enrollments:
| student_id | course_name |
|---|---|
| 1 | Matemáticas |
| 1 | Informática |
| 2 | Física |
Consulta con LEFT JOIN:
SELECT students.id, students.name, enrollments.course_name
FROM students
LEFT JOIN enrollments ON students.id = enrollments.student_id;
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemáticas |
| 1 | Eva | Informática |
| 2 | Peter | Física |
| 3 | Anna | NULL |
¡Hola, NULL! Como ves, para Anna, que no está inscrita en ningún curso, la info del curso falta y en vez de algo aparece NULL.
¿Cómo NULL afecta a las consultas?
NULL no es "cero" ni "cadena vacía", es ausencia de valor. Ese comportamiento tiene varias consecuencias interesantes (y a veces molestas):
Comparaciones con NULL:
Si escribes algo como WHERE course_name = NULL, la consulta no devuelve filas con NULL. ¿Por qué? Porque no puedes comparar valores directamente con NULL.
Para comprobar si hay NULL, tienes que usar operadores especiales:
WHERE course_name IS NULL
Operaciones matemáticas:
Cualquier operación con NULL devuelve NULL. Por ejemplo:
SELECT 5 + NULL; -- resultado: NULL
Funciones agregadas:
La mayoría de las funciones agregadas como SUM(), AVG(), ignoran NULL, pero COUNT(*) las cuenta como "filas existentes".
¿Cómo lidiar con NULL?
- Reemplazar
NULLpor valores claros usandoCOALESCE()
La función COALESCE() te deja reemplazar NULL por otro valor. Por ejemplo, si falta el curso, puedes poner "Sin curso":
SELECT
students.id,
students.name,
COALESCE(enrollments.course_name, 'Sin curso') AS course_name
FROM
students LEFT JOIN enrollments
ON students.id = enrollments.student_id;
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemáticas |
| 1 | Eva | Informática |
| 2 | Peter | Física |
| 3 | Anna | Sin curso |
Ahora se ve mucho mejor, ¿verdad?
- Filtrar valores
NULL
Si no quieres ver filas con NULL, puedes usar la condición WHERE ... IS NOT NULL. Por ejemplo:
SELECT
students.id,
students.name,
enrollments.course_name
FROM
students LEFT JOIN enrollments
ON students.id = enrollments.student_id
WHERE
enrollments.course_name IS NOT NULL;
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemáticas |
| 1 | Eva | Informática |
| 2 | Peter | Física |
Anna desaparece del resultado porque no tiene inscripciones a cursos.
- Contar teniendo en cuenta
NULL: ejemplo conCOUNT
Como mencioné antes, algunas funciones ignoran NULL y otras no. Por ejemplo:
Para contar todas las filas, incluidas las que tienen NULL:
SELECT COUNT(*) FROM students; -- Cuenta TODAS las filas (incluyendo donde `course_name` = NULL)
Para contar solo las filas donde no hay NULL:
SELECT COUNT(course_name) FROM enrollments;
- Expresiones condicionales con
CASE
Si no te gusta COALESCE() o quieres más flexibilidad, prueba usar CASE. Por ejemplo:
SELECT
students.id,
students.name,
CASE
WHEN enrollments.course_name IS NULL THEN 'Sin curso'
ELSE enrollments.course_name
END AS course_name
FROM
students LEFT JOIN enrollments
ON students.id = enrollments.student_id;
El resultado será igual que usando COALESCE(), pero CASE te deja escribir reglas más complejas.
- Usa
INNER JOINsi estás seguro de que no hayNULL
La forma más radical de evitar NULL es no dejar que aparezcan, usando INNER JOIN. Este tipo de join solo devuelve filas con coincidencias en ambas tablas:
SELECT
students.id,
students.name,
enrollments.course_name
FROM
students INNER JOIN enrollments
ON students.id = enrollments.student_id;
Sin sorpresas: solo estudiantes inscritos en cursos.
Resultado:
| id | name | course_name |
|---|---|---|
| 1 | Eva | Matemáticas |
| 1 | Eva | Informática |
| 2 | Peter | Física |
Si tus datos necesitan mostrar todos los valores, incluyendo NULL, INNER JOIN no te sirve, pero a veces es justo lo que necesitas.
GO TO FULL VERSION