Valores NULL de SQL explicados: IS NULL, COALESCE, NULLIF y las trampas que se deben evitar

  1. Inicio
  2. Blog
  3. Bases de datos y SQL

Bases de datos y SQL

Valores NULL de SQL explicados: IS NULL, COALESCE, NULLIF y las trampas que se deben evitar

NULL causa algunos de los errores más silenciosos en SQL, con consultas que se ejecutan sin errores pero pierden filas o distorsionan los promedios. Aprenda cómo se comporta realmente NULL, con ejemplos probados, y cómo manejarlo de forma segura.

9 min de lectura
Explicación de los valores NULL de SQL: IS NULL, COALESCE, NULLIF y las trampas a evitar

Puntos clave

  • NULL significa un valor faltante o desconocido. No es cero y no es una cadena vacía.
  • Pruébelo con IS NULL, porque = NULL nunca coincide con nada.
  • La mayoría de los cálculos con NULL dan NULL y WHERE mantiene solo las filas que son definitivamente verdaderas.
  • Los agregados omiten los NULL, lo que puede cambiar silenciosamente un promedio.

Una consulta se ejecuta sin errores y devuelve un número que parece razonable, pero faltan filas y el promedio es incorrecto. Los valores SQL NULL suelen ser la causa. NULL no se comporta como ningún valor normal y eso sorprende tanto a principiantes como a desarrolladores experimentados.

Esta guía muestra exactamente cómo se comporta NULL. Ejecutamos todas las consultas en SQLite 3.50 y los resultados mostrados provienen de esa ejecución. La mayor parte de este comportamiento es SQL estándar, y observamos dónde difieren las bases de datos, como el orden de clasificación NULL y el tratamiento de cadenas vacías por parte de Oracle.

¿Qué es NULO?

NULL es un marcador que significa que falta un valor o se desconoce. No es un valor en el sentido habitual, por lo que son cosas diferentes:

Valor Significado Ejemplo de una columna telefónica
NULO Desconocido o no proporcionado No sabemos el numero
'' Un valor de texto vacío conocido Enviado en blanco
0 el numero cero No es relevante para el texto, pero es real para las cantidades.

La diferencia es especialmente importante en el caso de las cantidades. Una bonificación de 0 significa que la persona no recibió nada. Una bonificación NULL significa que nadie lo sabe todavía.

La tabla de muestra

CREATE TABLE employees (
  id INT, name TEXT, phone TEXT, bonus INT, manager_id INT
);

INSERT INTO employees VALUES
 (1,'Meera','555-0101',500,NULL),
 (2,'Arjun',NULL,300,1),
 (3,'Sara','',NULL,1),
 (4,'Ravi',NULL,NULL,2);

Observe que Sara tiene una cadena vacía para el teléfono, mientras que Arjun y Ravi tienen NULL. Los dos reciben un trato muy diferente.

Prueba de NULL

Este es el error que casi todo el mundo comete al principio:

SELECT name FROM employees WHERE phone = NULL;
-- (no rows)

SELECT name FROM employees WHERE phone IS NULL;
-- Arjun
-- Ravi

SELECT name FROM employees WHERE phone IS NOT NULL;
-- Meera
-- Sara

La primera consulta es SQL válida y no da ningún error. Simplemente no devuelve nada, porque comparar algo con NULL nunca es cierto. Sara aparece debajo de IS NOT NULL, ya que una cadena vacía es un valor real. Sin embargo, en Oracle una cadena vacía se trata como NULL, lo cual es una excepción notable.

Lógica de tres valores

En la mayoría de los lenguajes de programación, una condición es verdadera o falsa. SQL agrega un tercer resultado: desconocido. Si no conoce un valor, no puede decir si es igual a 5. Y no se sabe que dos valores desconocidos sean iguales, razón por la cual NULL = NULL no es cierto. En nuestra prueba, todos estos arrojaron NULL:

SELECT NULL = NULL, NULL <> 1, 1 + NULL, 'a' || NULL;

-- NULL | NULL | NULL | NULL

La combinación de condiciones sigue reglas cuidadosas. Estos son los resultados de nuestra ejecución, donde 1 es verdadero y 0 es falso:

expresión Resultado ¿Por qué?
VERDADERO Y NULO NULO Depende de la parte desconocida
FALSO Y NULO Falso Falso sea lo que sea lo desconocido
VERDADERO O NULO Verdadero Cierto sea lo que sea lo desconocido
FALSO O NULO NULO Depende de la parte desconocida
NO NULO NULO Lo contrario de desconocido es desconocido

Filas que desaparecen de DONDE

WHERE mantiene una fila solo si su condición es verdadera. Las filas en las que se desconoce el resultado se eliminan, junto con las que son falsas. Esto lleva a resultados sorprendentes:

SELECT name FROM employees WHERE phone <> '555-0101';

-- Sara

Es de esperar que aparezcan Arjun y Ravi, ya que su teléfono ciertamente no es ese número. Pero se desconoce su teléfono, por lo que se desconoce el resultado y desaparecen. Para incluirlos, dígalo explícitamente: WHERE phone <> '555-0101' OR phone IS NULL. La negación tampoco ayuda:

SELECT name FROM employees WHERE NOT (bonus > 400);

-- Arjun

Sara y Ravi no tienen bonificación, por lo que no aparecen ni en bonus > 400 ni en su opuesto. Es fundamental recordar esto: una condición y su negación no siempre cubren todas las filas.

COALESCER: proporcionar un respaldo

COALESCE devuelve el primer valor no NULL de su lista y funciona en todas las bases de datos principales:

SELECT COALESCE(NULL, NULL, 'third', 'fourth');
-- third

SELECT name, COALESCE(phone, 'no phone') FROM employees;
-- Meera | 555-0101
-- Arjun | no phone
-- Sara  |
-- Ravi  | no phone

Sara todavía aparece en blanco porque una cadena vacía no es NULL. Existen funciones similares, como IFNULL en MySQL y SQLite, ISNULL en SQL Server y NVL en Oracle. COALESCE es la opción portátil. Nuestro punto anterior sobre los cálculos también se aplica aquí. bonus + 100 da NULL para cualquier persona sin bonificación, así que escriba COALESCE(bonus, 0) + 100 si tratar una bonificación faltante como cero es correcto para su negocio.

NULLIF: convierte un valor en NULL

NULLIF(a, b) devuelve NULL si los dos valores son iguales y, en caso contrario, devuelve a. Dos usos son especialmente útiles. Puede limpiar los valores de los marcadores de posición:

SELECT name, NULLIF(phone, '') FROM employees WHERE id = 3;
-- Sara | NULL

SELECT name FROM employees
WHERE COALESCE(NULLIF(phone, ''), '') = '';
-- Arjun
-- Sara
-- Ravi

Esa segunda consulta es una forma práctica de encontrar valores que “faltan o están en blanco”. También puede proteger contra la división por cero, lo que genera un error en muchas bases de datos:

SELECT total / NULLIF(quantity, 0) FROM sales;

Cuando quantity es 0, esto da NULL en lugar de fallar. En nuestra prueba, SELECT 100 / NULLIF(0, 0) devolvió NULL.

Los agregados omiten NULL

Aquí es donde NULL causa más daño a los informes:

SELECT COUNT(*), COUNT(bonus), SUM(bonus), AVG(bonus),
       AVG(COALESCE(bonus, 0))
FROM employees;

-- 4 | 2 | 800 | 400.0 | 200.0
expresión Resultado lo que significa
COUNT(*) 4 Todas las filas
COUNT(bonus) 2 Sólo filas con bonificación
SUM(bonus) 800 Los NULL se ignoran
AVG(bonus) 400 800 dividido por 2, no por 4
PROMEDIO(FUSIONAR(bonificación, 0)) 200 800 dividido por 4

Entonces, ¿cuál es el bono promedio, 400 o 200? Depende de lo que significa NULL en sus datos. Si NULL significa “no se pagó ningún bono”, entonces 200 es correcto. Si significa “aún no decidido”, entonces 400 puede tener razón. La base de datos no puede tomar esta decisión por usted, por lo que la pregunta debe dirigirse a alguien que conozca el negocio.

Una trampa relacionada: SUM sin valores es NULL en lugar de 0. Cuando sumamos solo las filas sin bonificación, obtuvimos NULL, mientras que COUNT devolvió 0. El código de la aplicación que espera un número puede fallar en esto, así que envuélvalo: COALESCE(SUM(bonus), 0).

Consejo: Cuando el total de un informe parezca incorrecto, compare COUNT(*) con COUNT(column). Cualquier espacio entre ellos le indica de inmediato cuántos NULL tiene esa columna.

GRUPO POR, clasificación y DISTINTO

Aunque los NULL “no son iguales” en las comparaciones, estas operaciones los tratan como un grupo:

SELECT bonus, COUNT(*) FROM employees GROUP BY bonus ORDER BY bonus;
-- NULL | 2
--  300 | 1
--  500 | 1

SELECT DISTINCT bonus FROM employees;
-- 500, 300, NULL

Consulte SQL GROUP BY y HAVING para obtener más información sobre la agrupación. El orden de clasificación es donde realmente difieren las bases de datos. SQLite y MySQL tratan a NULL como el valor más pequeño, mientras que PostgreSQL y Oracle lo tratan como el más grande. Entonces el mismo ORDER BY bonus DESC puede poner los NULL al final en uno y al principio en otro. PostgreSQL, Oracle y SQLite moderno le permiten indicar esto directamente, usando NULLS FIRST o NULLS LAST.

Se une

Una condición de unión que utiliza = nunca coincide con NULL, por lo que las filas con una clave NULL salen de una unión interna:

SELECT e.name FROM employees e
JOIN employees m ON m.id = e.manager_id;
-- Arjun, Sara, Ravi    (Meera is gone)

SELECT e.name, m.name FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id;
-- Meera | NULL
-- Arjun | Meera
-- Sara  | Meera
-- Ravi  | Arjun

Meera no tiene administrador, por lo que una combinación interna elimina esa fila silenciosamente. Un LEFT JOIN lo mantiene y también crea sus propios NULL para el lado que falta. Lea más en Explicación de uniones SQL.

La trampa NO ENTRAR

Un solo NULL en una lista NOT IN borra todos los resultados:

SELECT name FROM employees WHERE manager_id NOT IN (1);
-- Ravi

SELECT name FROM employees WHERE manager_id NOT IN (1, NULL);
-- (no rows)

La segunda forma significa manager_id <> 1 AND manager_id <> NULL, y esa última parte nunca puede ser cierta. Esto es particularmente peligroso con las subconsultas, donde un NULL puede pasar desapercibido. Utilice NOT EXISTS en su lugar, como se explica en nuestro tutorial de subconsultas SQL. Meera también falta en el primer resultado, ya que el manager_id de esa fila es NULL.

Diseñando con NULL

  • Utilice NOT NULL de forma predeterminada. Permita NULL solo cuando realmente pueda faltar un valor.
  • Agregue valores predeterminados sensatos. Por ejemplo, quantity INT NOT NULL DEFAULT 0.
  • No utilice valores mágicos. Una fecha de 1900-01-01 o una edad de -1 en lugar de “desconocido” corromperá sus cálculos.
  • Conozca el comportamiento ÚNICO. La mayoría de las bases de datos permiten varios NULL en una columna UNIQUE y nuestra prueba insertó dos sin error. SQL Server es una excepción, ya que normalmente lo permite.
  • Recuerde que una clave principal no puede ser NULL. Consulte clave principal versus clave externa.
  • Prueba con NULL. Los datos de prueba sin NULL ocultan estos errores. Inclúyalos a propósito, como lo haría con otros casos extremos.

Conclusión

Trate a NULL como “desconocido” y la mayor parte de su comportamiento comenzará a tener sentido: desconocido más uno es desconocido, y desconocido es igual a desconocido no se sabe que sea verdadero. Audite uno de sus propios informes esta semana. Verifique las columnas que aceptan valores NULL usando COUNT(*) contra COUNT(column), busque cualquier NOT IN y decida qué debería significar NULL en cada promedio.

Preguntas frecuentes

¿Qué es NULL en SQL?

NULL es un marcador de un valor faltante o desconocido. Es diferente de cero y de una cadena vacía y necesita un manejo especial en las comparaciones.

¿Por qué = NULL no funciona?

Comparar cualquier cosa con NULL da como resultado desconocido en lugar de verdadero, por lo que WHERE descarta la fila. Utilice IS NULL o IS NOT NULL para comprobarlo.

¿Cuál es la diferencia entre COALESCE e ISNULL?

COALESCE es SQL estándar y acepta muchos argumentos. ISNULL es específico de SQL Server y requiere dos. Para código portátil, prefiera COALESCE.

¿COUNT incluye valores NULL?

COUNT(*) cuenta todas las filas, incluidas aquellas con NULL. COUNT(columna) cuenta solo las filas donde esa columna no es NULL, lo que puede dar un número menor.

¿NULL es lo mismo que una cadena vacía?

No, en la mayoría de las bases de datos. Una cadena vacía es un valor conocido sin caracteres y NULL significa desconocido. Oracle es una excepción notable, ya que trata las cadenas vacías como NULL.

sigue aprendiendo

Trabajar con Stack Quora

¿Necesitas ayuda con pruebas, WordPress o SEO?

Ayudamos a los equipos a enviar mejor software y hacer crecer sus sitios. Cuéntenos en qué está trabajando y le sugeriremos un siguiente paso claro.

Sigue leyendo

Más guías sobre testing, IA y desarrollo moderno

¿Te gustó este artículo? Elige un tema y salta directo a nuestros tutoriales más recientes.

Inteligencia artificial

Explicación de las alucinaciones de la IA: por qué los modelos de lenguaje inventan cosas y cómo reducirlas

Se explicaron las alucinaciones de la IA: qué son, por qué los modelos de lenguaje las producen, tipos comunes, cómo reducirlas con conexión a tierr…

Leer artículo →
DevOps

Explicación de las variables de entorno: archivos .env, secretos y configuración bien hechos

Variables de entorno explicadas con ejemplos de Python que ejecutamos: leerlas y configurarlas, por qué cada valor es una cadena, archivos .env, her…

Leer artículo →
Desarrollo de software

Explicación de la limitación de velocidad de API: algoritmos, encabezados y manejo de errores 429

La limitación de la tasa de API se explica con una simulación que ejecutamos: depósito de tokens, ventana fija, ventana deslizante, 429 respuestas, …

Leer artículo →
Automatización de pruebas

Burlarse en Python: unittest.mock, patch y los errores que hacen que las pruebas mientan

Burlarse en Python con unittest.mock, probado: Mock y return_value, side_effect, parches donde se usa un nombre, especificación y autospec, fechas d…

Leer artículo →
Pruebas de software

Explicación de la cobertura del código: cobertura de línea versus sucursal y lo que realmente significa 100%

Cobertura del código explicada con una ejecución real de cobertura.py: cobertura de línea, rama y condición, lectura de un informe, por qué una cobe…

Leer artículo →
Bases de datos y SQL

DELETE vs TRUNCATE vs DROP en SQL: diferencias, reversión y cuándo usar cada uno

DELETE vs TRUNCATE vs DROP explicado con SQL probado: qué elimina cada uno, reversión, activadores, restablecimiento de identidad, velocidad y en qu…

Leer artículo →
Bases de datos y SQL

Vistas SQL explicadas: cree, use y evite los errores, con ejemplos

Vistas SQL explicadas con consultas que ejecutamos: creación de una vista, resultados en vivo, ocultación de columnas, rendimiento, vistas actualiza…

Leer artículo →
Desarrollo de software

Interfaz TypeScript versus tipo: diferencias reales, probadas con el compilador

Interfaz TypeScript versus tipo, verificado con el compilador real: qué pueden hacer ambos, qué puede hacer solo uno, fusión de declaraciones, exten…

Leer artículo →
Desarrollo de software

Python *args y **kwargs explicados: funciones flexibles con ejemplos claros

Python *args y **kwargs explicados con el código que ejecutamos: empaquetado y desempaquetado, orden de parámetros, argumentos solo de palabras clav…

Leer artículo →
Desarrollo de software

Funciones Lambda de Python: sintaxis, usos reales y cuándo no utilizarlas

Funciones lambda de Python explicadas con el código que ejecutamos: sintaxis, clasificación con clave, mapa y filtro, cierres, trampa de enlace tard…

Leer artículo →
Inteligencia artificial

¿Qué son los agentes de IA? Cómo funcionan, con un bucle de agente simple que puedes ejecutar

¿Qué son los agentes de IA? Una guía sencilla sobre el bucle del agente, las herramientas, la memoria y las barreras de seguridad, con un pequeño bu…

Leer artículo →
DevOps

Monitoreo versus observabilidad: la verdadera diferencia, con registros, métricas y seguimientos

Explicación del monitoreo versus observabilidad: fallas conocidas y desconocidas, registros, métricas y seguimientos, un recorrido por incidentes de…

Leer artículo →
DevOps

Docker Volumes versus Bind Mounts: persistir los datos del contenedor de la manera correcta

Se explican los volúmenes de Docker frente a los montajes de enlace: por qué desaparecen los datos del contenedor, volúmenes con nombre, montajes de…

Leer artículo →
Automatización de pruebas

TDD vs BDD: diferencias clave, una función creada en ambos sentidos y cuándo usar cada una

TDD vs BDD explicado con una característica de descuento construida en ambos sentidos: refactor rojo-verde con el código que ejecutamos, escenarios …

Leer artículo →
Pruebas de software

Pruebas de Aceptación de Usuario (UAT): Proceso, Lista de Verificación y Ejemplos Reales

Explicación de las pruebas de aceptación del usuario: quién las ejecuta, en qué se diferencia del control de calidad, un proceso de siete pasos, una…

Leer artículo →
Bases de datos y SQL

Valores NULL de SQL explicados: IS NULL, COALESCE, NULLIF y las trampas que se deben evitar

Los valores NULL de SQL se explican con las consultas que ejecutamos: lógica de tres valores, IS NULL, COALESCE, NULLIF, cómo los agregados, las uni…

Leer artículo →
Bases de datos y SQL

Declaración SQL CASE WHEN: sintaxis, ejemplos reales y errores comunes

CASO SQL CUANDO se explicó con las consultas que ejecutamos: formularios simples y buscados, orden de condiciones, pivotes con SUMA, trucos COUNT, c…

Leer artículo →
Desarrollo de software

¿Qué es JWT? Tokens web JSON explicados con un ejemplo práctico

¿Qué es JWT? JSON Web Tokens explicó: las tres partes, un token creado y manipulado en el código que ejecutamos, JWT vs sesiones, almacenamiento, to…

Leer artículo →
Desarrollo de software

Explicación del bucle de eventos de JavaScript: pila de llamadas, microtareas y temporizadores con ejemplos

El bucle de eventos de JavaScript explicado con el código que ejecutamos: pila de llamadas, colas de tareas y microtareas, por qué setTimeout 0 no e…

Leer artículo →
Desarrollo de software

Explicación de los generadores y el rendimiento de Python: ahorre memoria con ejemplos reales

Los generadores de Python y el rendimiento se explican con el código que ejecutamos: cómo se pausan y reanudan, midieron el ahorro de memoria, canal…

Leer artículo →
Inteligencia artificial

¿Qué son las incrustaciones? Los vectores y la similitud del coseno se explican de forma sencilla

¿Qué son las incrustaciones? Una guía en lenguaje sencillo sobre vectores, similitud de cosenos y búsqueda semántica, con un pequeño ejemplo que eje…

Leer artículo →
DevOps

Implementación azul-verde versus implementación canaria: diferencias, compensaciones y cómo elegir

Explicación de la implementación azul-verde versus canaria: cómo funciona cada uno, costo, riesgo y reversión, agrupación estable de usuarios que pr…

Leer artículo →
Automatización de pruebas

Pruebas inestables: qué las causa y cómo solucionarlas para siempre

Pruebas inestables explicadas con demostraciones que realizamos: las causas principales, cómo confirmar y diagnosticar una, correcciones adecuadas p…

Leer artículo →
Pruebas de software

Pruebas de carga frente a pruebas de estrés: diferencias, métricas y ejemplos de k6

Explicación de las pruebas de carga frente a las pruebas de estrés: qué prueba cada una, pruebas de picos y de absorción, las métricas que importan,…

Leer artículo →
Pruebas de software

Caso de prueba frente a escenario de prueba: diferencias clave, ejemplos y cuándo utilizar cada uno

Caso de prueba versus escenario de prueba explicado: definiciones claras, una tabla en paralelo, una función de restablecimiento de contraseña tomad…

Leer artículo →
Bases de datos y SQL

Optimización de consultas SQL: lea planes de ejecución y corrija consultas lentas, con tiempos

Optimización de consultas SQL probada en un millón de filas: lea planes de ejecución, agregue los índices correctos, corrija filtros no sargables, u…

Leer artículo →
Bases de datos y SQL

SQL UNION vs UNION ALL: diferencias, ejemplos y rendimiento probado

SQL UNION vs UNION ALL explicado con consultas que ejecutamos: duplicados, las reglas que siguen ambos, un error de datos real, rendimiento medido, …

Leer artículo →
Desarrollo de software

Tutorial de JavaScript Fetch API: GET, POST, manejo de errores y tiempos de espera

Un tutorial de JavaScript Fetch API probado en un servidor local: GET y POST, por qué 404 no arroja, un asistente reutilizable, cadenas de consulta,…

Leer artículo →
Desarrollo de software

Manejo de archivos Python: lectura, escritura, CSV, JSON y pathlib con ejemplos

El manejo de archivos Python se explica con el código que ejecutamos: modos abiertos, lectura de archivos grandes, CSV, JSON, pathlib, archivos bina…

Leer artículo →
Desarrollo de software

Clases y objetos de Python: tutorial de programación orientada a objetos con ejemplos reales

Clases y objetos de Python explicados con el código que ejecutamos: __init__, métodos, atributos de clase versus instancia, herencia, propiedades, m…

Leer artículo →
Inteligencia artificial

¿Qué es un modelo de lenguaje grande? Cómo funcionan los LLM, explicados sin exageraciones

¿Qué es un modelo de lenguaje grande? Los LLM explicados en lenguaje sencillo: tokens, incrustaciones, atención, entrenamiento, ventanas de temperat…

Leer artículo →
DevOps

Comandos de Linux para principiantes: la guía esencial de terminal con ejemplos

Comandos de Linux para principiantes, agrupados por tarea: navegación, archivos, visualización de registros, grep, canalizaciones, permisos, proceso…

Leer artículo →
Automatización de pruebas

Selenium vs Playwright: diferencias clave, comparación de códigos y cuál elegir

Comparación de Selenium vs Playwright: arquitectura, espera, soporte de navegador e idioma, depuración, la misma prueba en ambas herramientas, conse…

Leer artículo →
Pruebas de software

Partición de equivalencia: técnica de diseño de pruebas explicada con ejemplos resueltos

Explicación de la partición de equivalencia: cómo encontrar particiones válidas e inválidas, ejemplos prácticos para edades, contraseñas y cupones, …

Leer artículo →
Pruebas de software

Severidad vs Prioridad en Pruebas de Software: Diferencias, Matriz y Ejemplos Reales

Explicación de gravedad versus prioridad en las pruebas de software: definiciones claras, una matriz de cuatro vías con ejemplos, escalas de niveles…

Leer artículo →
Bases de datos y SQL

Tutorial de subconsultas SQL: tipos, subconsultas correlacionadas y EXISTENCIAS con ejemplos

Un tutorial de subconsultas SQL con consultas que ejecutamos: subconsultas escalares, IN, FROM y SELECT, subconsultas correlacionadas, EXISTS, la tr…

Leer artículo →
Bases de datos y SQL

Transacciones SQL y ACID explicados: COMMIT, ROLLBACK y niveles de aislamiento

Transacciones SQL y ACID explicadas con una transferencia bancaria que ejecutamos: COMMIT, ROLLBACK, puntos de guardado, bloqueos, niveles de aislam…

Leer artículo →
Desarrollo de software

Git merge vs rebase: diferencias, ejemplos y cuándo usar cada uno

Git merge vs rebase explicado con salida real del log, una tabla comparativa, la regla de oro del rebase y un flujo de trabajo seguro para equipos.

Leer artículo →
Desarrollo de software

List comprehension en Python: sintaxis, ejemplos y cuándo evitarla

List comprehension en Python explicada: sintaxis, filtros, if-else, bucles anidados, tiempos medidos y cuándo es mejor un bucle for normal.

Leer artículo →