¿Qué es NULL? NULL o el marcador NULL es la forma en que representamos un valor desconocido en SQL, por SQL me refiero al lenguaje de consulta estructurado estándar, no a MS SQL Server. La última oración nos retrotrae un poco a 1969, cuando el Dr. EF Codd definió por primera vez el estándar. NULL se vuelve necesario porque necesitamos pensar en términos de lo que se llama lógica de predicados de tres valores. Un predicado es la propiedad de una expresión que se cumple o no se cumple. A primera vista, uno pensaría en dos posibilidades:VERDADERO o FALSO. Sin embargo, existe una tercera posibilidad:DESCONOCIDA.
Tomemos un ejemplo. Suponiendo que un atributo (columna) en nuestra relación (Tabla) representa el Número de identificación fiscal (TIN) de un conjunto de propietarios de pequeñas empresas en Accra, Ghana. La columna para el registro de cada dueño de negocio se completará con su TIN y podemos usar esta columna para determinar algún otro atributo, como si está al día en el pago de impuestos. Sin embargo, hay dos posibilidades adicionales en este caso de uso:
- El propietario de la empresa tiene un TIN y está actualizado.
- El propietario de la empresa no tiene un TIN y (obviamente) no está actualizado.
Lo anterior describe lo que el Dr. Codd llamó lógica de predicados de cuatro valores. Sin embargo, el estándar SQL simplifica estas dos condiciones adicionales definiéndolas como desconocidas, es decir, NULL. No conocemos el TIN del propietario del negocio y no podemos determinar ningún otro valor a partir del atributo del propietario del negocio afectado. Entonces, NULL es DESCONOCIDO y es el tercer valor en la lógica estándar de predicados de tres valores.
NULL es especial
La definición de NULL requiere el tratamiento del marcador de forma diferente a los valores reales. Los siguientes son ejemplos:
- No existe el filtro "WHERE =NULL;". La expresión correcta sería “WHERE IS NULL;”. Lo mismo ocurre con la expresión inversa.
- Al ordenar SQL en orden ascendente, puede optar por enumerar los valores NULL al principio o al final. El valor predeterminado es enumerar NULL primero.
- No puede comparar valores NULL. Esto debería ser obvio ya que hemos dicho que NULL es DESCONOCIDO.
- Cuando un intento de concatenación involucra una columna NULL, el resultado es NULL.
Funciones comunes relacionadas con NULL
Las siguientes son tres funciones comunes relacionadas con NULL en SQL Server
ESNULL
ISNULL:reemplaza NULL con un valor de reemplazo especificado. El listado 1 y la figura 1 muestran ejemplos simples de ISNULL.
-- Listing 1: Simple Example of ISSNULL SELECT ISNULL (NULL, 3) NULLREPLACEMENT; SELECT ISNULL (NULL,'GREEN') NULLREPLACEMENT; SELECT ISNULL (NULL,'2018-12-25') NULLREPLACEMENT;
Fig. 1:Ejemplo simple de ISNULL
NULLIF
NULLIF devuelve NULL es el valor de los dos argumentos son iguales.
-- Listing 2: Simple Example of NULLIF SELECT NULLIF(3,3) AS NULLIFF; SELECT NULLIF(3,5) AS NULLIFF; SELECT NULLIF('RED','RED') AS NULLIFF; SELECT NULLIF('GREEN','RED') AS NULLIFF;
Fig. 2:Ejemplo simple de NULLIF
COALESCER
COALESCE devuelve el primer valor no NULL de la lista proporcionada. El Listado 1 muestra ejemplos de esto y la Figura 1 muestra el resultado de las consultas.
-- Listing 3: Simple Example of COALESCE SELECT COALESCE (NULL,'','GREEN','','') AS NULLRESPONSE; SELECT COALESCE (NULL,'GREEN','HOPE','') AS NULLRESPONSE; SELECT COALESCE (1,'','GREEN','','') AS NULLRESPONSE;
Fig. 3:Ejemplo simple de Coalesce
Tenga en cuenta que estos ejemplos simples exponen al uso la naturaleza de NULL. NULL y espacio en blanco NO es lo mismo. En la primera declaración, COALESCE devuelve un espacio en blanco que nos muestra que un espacio en blanco es el primer valor no NULL en la lista.
Diferencias entre ISNULL y COALESCE
Las diferencias entre ISNULL y COALESCE han sido objeto de varios artículos en línea, así como de libros como los que se enumeran en la sección de referencias. Estas diferencias se resumen de la siguiente manera:
- ISNULL es propiedad de SQL Server, mientras que COALESCE es una función estándar de ANSI. Esto implica que, por portabilidad, se prefiere COALESCE.
- ISNULL toma solo dos argumentos mientras que COALESCE puede tomar más de dos argumentos.
- El tipo de datos del valor devuelto por ISNULL está determinado por el tipo de datos del primer argumento, mientras que el tipo de datos del valor devuelto por COALESCE está determinado por el tipo de datos de la lista con la prioridad más alta.
- Cuando ambas funciones se usan con subconsultas, ISNULL funciona mejor porque COALESCE se traduce internamente a una expresión CASE, por lo que tiende a repetir escaneos.
Itzik Ben-Gan también explora otras implicaciones de la conversión de COALESCE a una expresión de caso en su artículo cuyo enlace se proporciona al final de este artículo.
Ejemplos de casos de uso
Queremos mostrar en un portal web la lista de clientes basada en ciertos criterios de la tabla que estamos creando en el Listado 4. Las tareas 1 y 2 brindan posibles requisitos y usamos ISNULL y COALESCE para cumplir con los requisitos.
--Listing 4: Table Creation Script CREATE TABLE CUSTOMER (ID INT IDENTITY (1,1) ,FIRSTNAME VARCHAR(50) ,LASTNAME VARCHAR(50) ,SEX CHAR(1) ,ADDRESS VARCHAR(300) ,FIRSTTRANDATE DATETIME ,PHONENUMBER1 BIGINT ,PHONENUMBER2 BIGINT ,PHONENUMBER3 BIGINT); GO INSERT INTO CUSTOMER VALUES ('KENNETH','IGIRI','M','ACCRA, GHANA',GETDATE(),'0245335678','0555335678',NULL); INSERT INTO CUSTOMER VALUES ('RICHARD','HANO','M','BUDAPEST, HUNGARY',GETDATE(),'889189400122',NULL,NULL); INSERT INTO CUSTOMER VALUES ('GEORGINA','APPIAH','F','ACCRA, GHANA','09-16-2018','02456665678','0275339678',NULL); INSERT INTO CUSTOMER VALUES ('HOWARD','KLEVIA',NULL,'HAGUE, SWITZERLAND','02-16-2017','3499285782',NULL,NULL); INSERT INTO CUSTOMER VALUES ('ZEN','GREGOR',NULL,'SHANGHAI, CHINA','06-23-2018','0245335678','0555335678',NULL); INSERT INTO CUSTOMER VALUES ('IHEOMA','AWA','F','LAGOS, NIGERIA',GETDATE(),'0245335678','0555335678',NULL);
Fig. 4 Tabla de muestra
Tarea 1 :devuelve la lista de todos los clientes que no proporcionaron un número de teléfono alternativo.
--Listing 5: Table List of Customers with no Secondary Phones --A: The Simple Answer SELECT * FROM CUSTOMER WHERE PHONENUMBER2 IS NULL ; --B: Presenting the Result Set Better SELECT FIRSTNAME ,LASTNAME ,ADDRESS ,FIRSTTRANDATE ,PHONENUMBER1 AS [PRIMARY PHONE NUMBER] ,ISNULL(CAST(PHONENUMBER2 AS VARCHAR), 'NO SECONDARY PHONE') AS [SECONDARY PHONE NUMBER] FROM CUSTOMER WHERE PHONENUMBER2 IS NULL ;
Usando COALESCE (o ISNULL), podemos presentar la información requerida mucho mejor usando un texto que dice "Sin teléfono secundario".
Fig. 5 Conjunto de resultados para el Listado 5
Tarea 2 :devuelve la lista de todos los clientes, su número de teléfono principal, y cualquier otro número de teléfono alternativo.
--Listing 6: Table List of Customers with an Other Alternate Number SELECT FIRSTNAME ,LASTNAME ,ADDRESS ,FIRSTTRANDATE ,PHONENUMBER1 AS [PRIMARY PHONE NUMBER] ,COALESCE(CAST(PHONENUMBER2 AS VARCHAR),CAST(PHONENUMBER3 AS VARCHAR), 'NO OTHER PHONE') AS [OTHER PHONE NUMBER] FROM CUSTOMER ;
Fig. 6 Conjunto de resultados para el Listado 6
En este caso, ISNULL no es una opción ya que estamos pasando tres argumentos.
Conclusión
En este artículo, analizamos el concepto de NULL en relación con la lógica de predicados de tres valores y describimos funciones populares que usamos en SQL Server para manejar conjuntos de datos que contienen valores NULL. También hemos visto ejemplos de cómo se pueden usar estas funciones. Muchas otras referencias profundizan en el uso, beneficios y limitaciones de estas funciones. Recomiendo encarecidamente los libros y blogs de Itzik Ben-Gan como buenas fuentes de información.
Referencias
- NULLIF (Transact-SQL)
- COALESCE (Transact-SQL)
- Artículo de Itzik Ben-Gan