🎯 Quedan pocos días este mes Apoya SQLTest.online y ayúdanos a mantener la práctica de SQL gratuita para todos. Dona hoy →
Código SQL copiado al portapapeles

Lección 2.4 · Tiempo de lectura: ~6 min

IS NULL e IS NOT NULL son la única forma fiable de filtrar valores ausentes en SQL. En esta lección verás por qué WHERE column = NULL no encuentra nada, cómo encontrar filas con valor y sin él, y cómo NULL saca filas en silencio de las condiciones con NOT, <> y NOT IN. Los ejemplos usan la tabla rental de la base de datos Sakila, donde return_date es NULL en las películas que aún no se han devuelto.

SQL IS NULL e IS NOT NULL

Una comparación con NULL da UNKNOWN y WHERE solo conserva las filas TRUE, por eso = NULL no encuentra nada e IS NULL encuentra las filas sin valor

Por qué = NULL no encuentra nada

NULL significa «el valor es desconocido». Cualquier comparación con un valor desconocido también es desconocida: return_date = NULL no es verdadero ni falso, es UNKNOWN. WHERE solo conserva las filas en las que la condición es TRUE, así que la consulta no devuelve nada:

SELECT COUNT(*) AS not_returned FROM rental WHERE return_date = NULL;

Resultado: 0, aunque 183 alquileres no tienen fecha de devolución.

Lo mismo ocurre con <>, >, < y cualquier otro operador de comparación.

IS NULL

IS NULL es una comprobación especial que es TRUE cuando falta el valor:

SELECT COUNT(*) AS not_returned FROM rental WHERE return_date IS NULL;

Resultado: 183.

SELECT rental_id, rental_date, customer_id
FROM rental
WHERE return_date IS NULL
ORDER BY rental_date
LIMIT 3;

Resultado: los alquileres 14098 (cliente 554), 13421 (cliente 366) y 15542 (cliente 111), las películas más antiguas que siguen sin devolverse.

IS NOT NULL

IS NOT NULL es lo contrario: TRUE cuando la columna tiene un valor.

SELECT COUNT(*) AS returned FROM rental WHERE return_date IS NOT NULL;

Resultado: 15861. Junto con los 183 alquileres sin fecha de devolución, son las 16044 filas.

NULL queda fuera de una condición y de su NOT

Parece natural que una condición y su NOT dividan la tabla en dos. Con NULL no es así:

SELECT
    (SELECT COUNT(*) FROM rental WHERE return_date >= '2005-08-01') AS after_august,
    (SELECT COUNT(*) FROM rental WHERE NOT (return_date >= '2005-08-01')) AS before_august,
    (SELECT COUNT(*) FROM rental) AS total;

Resultado: 8207 + 7654 = 15861, no 16044. Para las 183 filas sin fecha de devolución, ambas condiciones son UNKNOWN, y NOT UNKNOWN sigue siendo UNKNOWN.

Para conservar esas filas, pídelas de forma explícita con OR ... IS NULL:

SELECT COUNT(*) AS late_or_unknown
FROM rental
WHERE return_date >= '2005-08-01' OR return_date IS NULL;

Resultado: 8390 = 8207 + 183.

La trampa de NOT IN

NOT IN es una cadena de comparaciones <> unidas con AND. Si la lista contiene NULL, una de ellas siempre es UNKNOWN y ninguna fila pasa:

SELECT COUNT(*) AS films FROM film WHERE language_id NOT IN (2, 3);

Resultado: 1000.

SELECT COUNT(*) AS films FROM film WHERE language_id NOT IN (2, NULL);

Resultado: 0, porque language_id <> NULL es UNKNOWN para todas las películas.

Nadie escribe NULL a mano en una lista, pero la lista a menudo sale de una columna, y basta un solo NULL para vaciar el resultado. Antes de usar NOT IN, asegúrate de que los valores no pueden ser NULL.

Mostrar un valor en lugar de NULL

COALESCE devuelve el primero de sus argumentos que no es NULL. Es útil para mostrar un valor legible en el resultado:

SELECT rental_id, rental_date, COALESCE(return_date, 'not returned') AS returned_at
FROM rental
WHERE customer_id = 554 AND rental_date >= '2005-08-21'
ORDER BY rental_date;

Resultado: 4 alquileres; el primero, 14098, muestra «not returned».

Esto es MySQL. En PostgreSQL y SQL Server los dos argumentos deben ser del mismo tipo, así que allí la fecha se convierte primero en texto. COALESCE y otras funciones se ven en el módulo de funciones.


Conclusiones clave:

  • Cualquier comparación con NULL (=, <>, >, <) da UNKNOWN, y WHERE descarta esas filas.
  • Usa IS NULL para encontrar filas sin valor e IS NOT NULL para encontrar filas con valor.
  • Una condición y su NOT juntos no cubren las filas en las que la columna es NULL; añade OR column IS NULL para conservarlas.
  • NOT IN no devuelve ninguna fila si la lista contiene NULL.
  • COALESCE(column, value) muestra un valor de sustitución en lugar de NULL.

Preguntas frecuentes

¿Por qué WHERE column = NULL no devuelve filas?

Una comparación con NULL es UNKNOWN, no TRUE, y WHERE solo conserva las filas TRUE. Usa WHERE column IS NULL.

¿IS NOT NULL es lo mismo que NOT (column = NULL)?

No. column = NULL es UNKNOWN, y NOT UNKNOWN también es UNKNOWN, así que NOT (column = NULL) tampoco encuentra nada. IS NOT NULL es TRUE para cada fila que tiene un valor.

¿COUNT(column) cuenta los valores NULL?

No. COUNT(*) cuenta filas, COUNT(column) cuenta solo los valores de la columna que no son NULL. Las funciones de agregación tienen su propio módulo.

Preguntas de entrevista

¿Por qué las consultas SQL usan IS NULL en lugar de = NULL?

NULL significa un valor desconocido, y comparar cualquier cosa con un valor desconocido da UNKNOWN, no TRUE ni FALSE. WHERE solo conserva las filas en las que la condición es TRUE, así que = NULL nunca encuentra nada. IS NULL es una prueba aparte que devuelve TRUE o FALSE.

¿Por qué NOT IN puede devolver un resultado vacío?

x NOT IN (a, b) significa x <> a AND x <> b. Si la lista contiene NULL, x <> NULL es UNKNOWN para cada fila, todo el AND no puede ser TRUE y no se devuelve ninguna fila. Ocurre cuando la lista sale de una subconsulta cuya columna tiene valores NULL.

¿Cómo se conservan las filas con NULL en un filtro?

Añade el caso NULL de forma explícita: WHERE return_date >= '2005-08-01' OR return_date IS NULL. Si no, las filas con NULL quedan descartadas tanto por la condición como por su negación.

Intenta resolver las siguientes tareas para reforzar lo que aprendiste en esta lección.

  1. Direcciones Sin Códigos Postales
  2. Lista filtrada de productos
  3. Pingüinos de Peso Más Ligero
  4. Pingüinos cuyo sexo es desconocido
  5. Pingüinos con datos ausentes