Documentación FirebirdBase de Datos FirebirdGuía de NULL en Firebird → NULL en expresiones
Firebird home Firebird home Anterior: ¿Qué es NULL?Inicio: Documentación FirebirdSubir: Guía de NULL en FirebirdSiguiente: Manejo de NULL en UDF's

NULL en expresiones

Expresiones que devuelven NULL
NULL en expresiones booleanas
Más lógica (o no)
NULL en funciones agregadas

Como muchos de nosotros hemos encontrado, para nuestro disgusto, NULL es contagioso: úsalo en una expresión numérica, texto o fecha/hora y el resultado siempre es NULL. Úsalo en una expresión lógica y el resultado depende del tipo de operación y el resto de valores implicados.

Por cierto, nota que en versiones anteriores a Firebird 2.0 es normalmente ilegal usar la constante NULL directamente en operaciones o comparaciones. Cuando veas NULL en las expresiones siguientes, léelas como “un campo, variable u otra expresión que resuelve en NULL”.

Expresiones que devuelven NULL

Las expresiones en esta lista siempre devuelven NULL:

  • 1 + 2 + 3 + NULL

  • 'Hogar ' || 'dulce ' || NULL

  • MiCampo = NULL

  • MiCampo <> NULL

  • NULL = NULL

  • not (NULL)

Si tienes dificultades en entender por qué, recuerda que NULL significa “desconocido”. Además mira en la siguiente tabla donde hay explicaciones por caso. En la tabla, no hemos escrito NULL en las expresiones (como ya hemos dicho, es, a menudo, ilegal); en vez de ello, hemos usado dos entidades A y B que son ambas NULL. A y B pueden ser campos, variables o subexpresiones enteras en su derecho – como son NULL, se comportan de la misma manera que expresiones cerradas.

Tabla 3. Operaciones sobre entidades NULL A y B

Si A y B son NULL, entonces: Es: Porque:
1 + 2 + 3 + A NULL Si A es desconocido, entonces 6+A también es desconocido.
'Hogar ' || 'dulce ' || A NULL Si A es desconocido, entonces 'Hogar dulce ' || A es también desconocido.
MiCampo = A NULL Si A es desconocido, no puedes decir que MiCampo tenga el mismo valor…
MiCampo <> A NULL ...ni puedes decir que MiCampo tenga distinto valor!
A = B NULL Con A y B desconocidos, es imposible saber si son iguales.
not (A) NULL Si A es desconocido, su inverso también.

NULL en expresiones booleanas

Hemos visto que not(NULL) devuelve NULL. Para los operadores and y or, las cosas son un poco más complicadas:

  • NULL or false = NULL

  • NULL or true = true

  • NULL or NULL = NULL

  • NULL and false = false

  • NULL and true = NULL

  • NULL and NULL = NULL

El SQL de Firebird no tiene un dato de tipo booleano (lógico); no hay unas constantes true o false existentes. En la columna de la izquierda de la siguiente tabla (true) y (false) representan expresiones que devuelven true/false.

Tabla 4. Operaciones lógicas (booleanas) sobre una entidad NULL A

Si A es NULL, entonces: Es: Porque:
A or (false) NULL A or false” siempre tiene el valor de A, que es desconocido.
A or (true) true A or true” siempre es true. El valor de A no importa.
A or A NULL A or A” siempre equivale a A, que es NULL.
A and (false) false A and false” es siempre false. El valor de A no importa.
A and (true) NULL A and true” siempre tiene el valor de A, el cuál es desconocido.
A and A NULL A and A” siempre equivale a A, que es NULL.

Todos estos resultados están en concordancia con la lógica booleana. El hecho de que, para calcular “X or true” y “X and false”, simplemente no necesites saber el valor de X, es también la base de una característica que conocemos en varios lenguajes de programación: evaluación de circuitos cortos booleanos.

Más lógica (o no)

Los resultados de circuitos cortos obtenidos arriba, pueden llevarte a las siguientes ideas:

  • 0 veces x equivale a 0 para cada x. Por tanto, igual que el valor de x es desconocido, 0 * x es 0. (Nota: esto sólo sucede si el tipo de dato de x sólo contiene números, no NaN o infinitos).

  • La cadena vacía está ordenada lexicográficamente antes de cada otra cadena. Por tanto S >= '' es verdad siempre independientemente del valor de S.

  • Cada valor equivale a sí mismo, independientemente de si es desconocido o no. Por tanto, aunque A = B justificadamente se devuelve NULL si A y B son entidades NULL diferentes, A = A siempre debería devolver true, igual que A es NULL.

¿Cómo está esto implementado en el SQL de Firebird? Bueno, siento informarte que, a pesar de esta convincente lógica – y la analogía con los resultados explicados arriba – las siguientes expresiones se resuelven todas con NULL:

  • 0 * NULL

  • NULL >= ''

  • '' <= NULL

  • A = A (con A como un campo o variable NULL)

Demasiado para la coherencia.

NULL en funciones agregadas

En funciones agregadas como COUNT, SUM, AVG, MAX, y MIN, NULL se maneja de manera diferente: para calcular el resultado, sólo se tienen en consideración los campos con valores no-NULL. Esto es, si tienes esta tabla:

MiTabla

ID Nombre Sueldo
1 Juan 37
2 Perico <NULL>
3 Andrés 5
4 Roberto 12
5 Antonio <NULL>

...la sentencia select sum(Sueldo) from MiTabla devuelve 54, que es 37+5+12. Si sumáramos todos los valores, el resultado debería haber sido NULL. Para AVG, los campos no-NULL son sumados y la suma dividida entre el número de campos no-NULL.

Hay una excepción en esta regla: COUNT(*) devuelve el número de todas las filas, incluidas todas aquellas con campos en NULL. Pero COUNT(NombreDeCampo) se comporta como las otras funciones agregadas y cuenta aquellas filas que tienen campos con contenido no-NULL.

Otra cosa a tener en cuenta: COUNT(*) y COUNT(NombreDeCampo) jamás devuelven NULL: si no hay filas en el grupo, ambas funciones devuelven 0. Además, COUNT(NombreDeCampo) devuelve 0 si todos los campos NombreDeCampo del grupo son NULL. Las otras funciones agregadas devuelven NULL en tales casos. Ten en cuenta que SUM devuelve NULL si se usa en un grupo de registros vacío, lo que es contrario a la lógica común.

Anterior: ¿Qué es NULL?Inicio: Documentación FirebirdSubir: Guía de NULL en FirebirdSiguiente: Manejo de NULL en UDF's
Documentación FirebirdBase de Datos FirebirdGuía de NULL en Firebird → NULL en expresiones