Volver a la lista de artículos Artículos
Lectura de 6 minutos

Entendiendo el Uso de NULL en la Lógica de Tres Valores de SQL

Los NULLs son necesarios en las bases de datos relacionales, y aprender a usarlos es fundamental para el éxito de SQL. Sin embargo, los NULLs también deben ser manejados con cuidado, como explicamos en este post.

En las bases de datos relacionales, no siempre tenemos un valor que poner en una columna. Por ejemplo, supongamos que tenemos una tabla llamada "personas" que tiene las columnas "nombre", "apellido", "fecha de nacimiento" y "fecha de matrimonio". ¿Qué valor almacenaremos en la columna "fecha_de_matrimonio" para las personas solteras? En ese caso, la columna no podría tener un valor porque las personas solteras no están casadas. Necesitamos una forma de indicar que no tenemos un valor para esta columna. Afortunadamente, tenemos algo así: el valor NULL, que se utiliza ampliamente en las bases de datos relacionales.

Los NULL pueden aplicarse a cualquier tipo de datos: enteros, fechas, VARCHARs, o cualquier otro tipo de columna. Pero debemos tener cuidado cuando creamos cálculos o expresiones que contienen uno o más operadores con un valor NULL. Veamos por qué.

NULLs y lógica de tres valores

La razón por la que los NULLs pueden confundir a la gente tiene que ver con algo llamado lógica de tres valores. Mientras que la lógica binaria o booleana tiene dos valores ("verdadero" y "falso"), la lógica de tres valores (abreviada como 3VL y también conocida como lógica ternaria) tiene un valor adicional: "desconocido".

Vamos a ilustrar la 3VL con un escenario sencillo. Supongamos que queremos obtener los nombres de los empleados que ganan más de 1.200 euros al mes. La tabla employee tabla tiene el siguiente aspecto:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1000 NULL

Probamos la siguiente consulta:

SELECT * FROM employee WHERE bonus + salary > 1200;

El resultado es:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500

Deberíamos ver tres registros en el conjunto de resultados, pero sólo hay dos. ¿Por qué no se incluye a Peter White? La razón está relacionada con el valor NULL de la columna bonus. En SQL, toda operación aritmética que incluye un operando con un valor NULL devuelve un resultado NULL.

Así que, teniendo esto en cuenta, observe cómo se evaluó el registro de Peter White:

1800 + NULL > 1200

En otras palabras, el salario de Peter (1.800) y su bonificación (NULL) sumaban NULL. Podemos reducir esta condición a :

NULL > 1200

Entonces, ¿es NULL mayor que 1.200? Recuerda que NULL representa un valor inexistente, lo que significa que no tenemos nada que comparar con 1.200: no podemos saber si esta afirmación es verdadera o falsa. Así es como funciona la lógica de tres valores. Cuando tenemos un valor NULL en una condición, el resultado de esta condición será "desconocido".

Entendiendo la Lógica de Tres Valores en las Consultas SQL

Para entender cómo funciona la lógica de tres valores, vamos a ver el proceso paso a paso. Primero, piense en cómo se filtran los registros en la cláusula WHERE. Sólo los registros que se evalúan como "verdadero" en la cláusula WHERE forman parte del conjunto de resultados de la consulta. Los registros que se evalúan como "falso" o "desconocido" no forman parte del resultado. Por ello, el registro de Peter White quedó fuera de los resultados de la consulta anterior. Su salario total se evalúa como "desconocido" en la cláusula WHERE; "1800 + NULL > 1200" es "desconocido" porque no podemos saber qué es NULL.

Las tablas AND, OR y NOT también son importantes en la lógica de tres valores, así que las examinaremos individualmente y veremos cómo calculan. Empecemos con la tabla NOT:

Value NOT Result
True False
False True
Unknown Unknown

A continuación, veamos la tabla AND:

AND True False Unknown
True True False Unknown
False False False False
Unknown Unknown False Unknown

Analicemos por qué "falso " Y "desconocido" equivale a "falso". Un "falso" es suficiente para que todo el resultado sea "falso" en una operación AND. Esto es cierto independientemente de que el segundo valor sea "verdadero", "falso" o "desconocido".

Por último, tenemos la tabla OR:

OR True False Unknown
True True True True
False True False Unknown
Unknown True Unknown Unknown

Probemos una consulta que utilice el operador OR:

SELECT * FROM employee WHERE salary < 1500 OR bonus > 200 

El resultado es el siguiente:

First Name Last Name Salary Bonus
John Smith 1000 500
Mary Smith 1000 1500
Nick Perry 1000 NULL

Observe que un registro que contiene un valor NULL en la columna "bonus" aparece en el resultado, pero el otro registro NULL no aparece. La razón es el operador OR. Como la condición salario < 1500 es verdadera, no es necesario evaluar la condición bono > 200.

Cómo lidiar con la variable desconocida

A veces puede evitar el uso de valores "desconocidos" en las condiciones WHERE convirtiendo los valores NULL en otros valores (como 0) utilizando la función COALESCE(). Considere los ejemplos anteriores. Si convirtiera todos los NULL a "0" antes de comparar el valor en el WHERE, obtendría resultados diferentes a los mostrados anteriormente. Sin embargo, esta conversión puede o no ser posible, dependiendo de la semántica de la consulta. Aun así, vamos a intentarlo y a ver qué pasa.

SELECT * FROM employee WHERE coalesce(bonus,0) > 200 OR salary < 1500

La consulta sólo generará resultados "verdaderos" o "falsos". En este caso, se aplicará la lógica de dos valores.

Supongamos que recibimos una orden para dar un aumento salarial del 5% a los empleados que ganan menos de 1.600 euros al mes. ¿Cómo debemos escribir esta consulta? Intentémoslo:

UPDATE employee
SET salary = salary *1.05
WHERE salary + bonus <= 1600

Aquí están los resultados:

First Name Last Name Salary Bonus
John Smith 1050 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1000 NULL

Un momento, ¡el sueldo de Nick no ha cambiado! ¡Eso no es justo! De nuevo, el resultado "desconocido" de la condición "salario + bonificación <= 1600" para el registro de Nick está causando un problema.

Nuestro segundo intento es mejor:

UPDATE employee
SET salary = salary *1.05
WHERE salary + coalesce(bonus,0) <= 1600

Como podemos ver en el siguiente resultado de la consulta, el salario de ambos registros (John y Nick) se ha modificado.

First Name Last Name Salary Bonus
John Smith 1050 500
Mary Smith 1000 1500
Peter White 1800 NULL
Nick Perry 1050 NULL

Pruébelo usted mismo

Puede haber muchas cláusulas WHERE diferentes que se evalúen como "desconocido" o "falso". ¿Por qué no prueba usted mismo algunas consultas SQL y ve cuáles devuelven valores "verdaderos", "falsos" o "desconocidos"? LearnSQL.es puede enseñarte todo sobre la cláusula WHERE y sus condiciones. ¡Pruébalo gratis!