10 - LIKE y Valores NULL

Búsquedas por patrones de texto y gestión de datos inexistentes o indeterminados


Antes de finalizar la primera parte del curso deben tratarse dos aspectos relevantes del lenguaje que se han quedado en el tintero: el operador LIKE, y el valor NULL.


El Operador LIKE

Este operador se aplica a datos de tipo cadena y se usa para buscar registros, es capaz de hallar coincidencias dentro de una cadena bajo un patrón dado, por ejemplo:

¿Qué empleados su primer apellido comienza por "R"?

Veamos primero la consulta SQL que responde a esto:


select *
  from EMPLEADOS
 where APELLIDOS like 'R%'
            
ID_EMPLEADONOMBREAPELLIDOSF_NACIMIENTOSEXOCARGOSALARIO
2ElenaRubio Cuestas1978-09-25MSecretaria1300.00
4MargaritaRodriguez Garcés1992-05-16MSecretaria1325.50

El interés de la anterior consulta se centra en la expresión: APELLIDOS LIKE 'R%'

donde LIKE es el operador, APELLIDOS es el operando variable que toma valores para cada registro de la tabla EMPLEADOS, y el operando constante: "R%", es un patrón de búsqueda donde el "%" representa un comodín que junto con el operador LIKE tiene el cometido de reemplazar a cualquier cadena de texto, incluso la cadena vacía, para evaluar la expresión booleana. De modo que cualquier valor que haya en el campo APELLIDOS que empiece por una "R" seguido de cualquier cosa (%), dará cierto para la expresión: APELLIDOS LIKE 'R%'.

Veamos otro ejemplo: ¿Qué empleados su segundo apellido termina en "N"?

En este caso interesa que el campo APELLIDOS empiece por cualquier cadena y acabe con una "N", por lo tanto la expresión que nos filtrará adecuadamente esto es: APELLIDOS LIKE '%N'


select *
  from EMPLEADOS
 where APELLIDOS like '%N'
            
ID_EMPLEADONOMBREAPELLIDOSF_NACIMIENTOSEXOCARGOSALARIO
1CarlosJiménez Clarín1985-05-03HMozo1500.00
3JoséCalvo Sisman1990-11-12HMozo1400.00

En MariaDB la comparación de cadenas por defecto no es sensible a mayúsculas, de ahí que aún indicando una "N" mayúscula encuentre los apellidos acabados en "n" minúscula.

Obsérvese como en este caso el "%" debe aparecer antes que la "N" en el patrón de búsqueda, puesto que queremos que los apellidos acaben en "N" y no que comiencen por "N".

Veamos una última aplicación de este recurso. ¿Qué devuelve esta consulta?:


select *
  from EMPLEADOS
 where APELLIDOS like '%AR%'
            
ID_EMPLEADONOMBREAPELLIDOSF_NACIMIENTOSEXOCARGOSALARIO
1CarlosJiménez Clarín1985-05-03HMozo1500.00
4MargaritaRodriguez Garcés1992-05-16MSecretaria1325.50

Pues está devolviendo aquellos registros que el campo APELLIDOS contiene la cadena: "AR", ya sea al principio, al final, o en cualquier posición intermedia. De ahí que en el patrón de búsqueda encontremos la cadena "AR" acompañada de comodines a ambos lados.

Este recurso resulta muy útil para buscar coincidencias en campos sin necesidad de buscar el valor exacto. Si se nos pide buscar al empleado José Calvo, podemos limitarnos a buscar cualquier valor que contenga la cadena "Calvo" en el campo APELLIDOS para localizar el registro.


El Valor NULL

Cuando se diseña una tabla en la base de datos, una de las propiedades que se establece para los campos de la tabla es si pueden contener o no un valor nulo. Por ejemplo, supongamos que tenemos una flota de vehículos. En la tabla VEHICULOS se guardan los datos de cada unidad, datos como el modelo, que obviamente no puede ser nulo puesto que todo vehículo pertenece a un modelo, pero también por ejemplo la fecha de la última revisión obligatoria, cuyo valor sí puede ser nulo, especialmente si el vehículo es nuevo y todavía nunca se ha sometido a dicha revisión. Por tanto ya se ve que hay campos que no pueden ser nulos y otros sí, dependiendo de qué información se guarda.

Para ilustrar las particularidades del valor NULL tomemos la tabla VEHICULOS:

ID_VEHICULOMARCAMODELOPROX_ITVULTI_ITV
1Alfa RomeoBrera2011-10-20NULL
2SeatPanda2009-12-012008-12-01
3BMWX32010-07-18NULL
4CitroënC22010-08-242009-08-24
5FordFiesta2011-04-22NULL

En los Datos se observa como tres de las cinco unidades nunca han pasado la revisión obligatoria, puesto que el valor para el campo ULTI_ITV (última inspección técnica del vehículo) es nulo.


El Operador IS NULL

Este operador permite establecer en la cláusula WHERE de una consulta SQL condiciones para filtrar por campos de valor nulo, por ejemplo: ¿Qué vehículos nunca han pasado la ITV?


select *
  from VEHICULOS
 where ULTI_ITV is null
            
ID_VEHICULOMARCAMODELOPROX_ITVULTI_ITV
1Alfa RomeoBrera2011-10-20NULL
3BMWX32010-07-18NULL
5FordFiesta2011-04-22NULL

Los vehículos que han pasado como mínimo una vez la ITV serán aquellos que el campo ULTI_ITV no contenga un valor nulo, para conocer estos datos debemos establecer la siguiente condición:


select *
  from VEHICULOS
 where ULTI_ITV is not null
            
ID_VEHICULOMARCAMODELOPROX_ITVULTI_ITV
2SeatPanda2009-12-012008-12-01
4CitroënC22010-08-242009-08-24

Por tanto ya se ve que el valor nulo es un poco especial, en realidad es un valor indeterminado. Una muestra de ello es la excepción que se da a la afirmación que se hizo en la lección 5 sobre operadores: "si negamos la cláusula WHERE de una consulta SQL con el operador NOT, se obtienen los registros que antes se ignoraban y se ignoran los que antes se seleccionaban".

Veamos una muestra de ello. La siguiente consulta SQL devuelve los vehículos que pasaron la ITV durante el 2008:


select *
  from VEHICULOS
 where ULTI_ITV between '20080101' and '20081231'
            
ID_VEHICULOMARCAMODELOPROX_ITVULTI_ITV
2SeatPanda2009-12-012008-12-01

Es de esperar entonces que al negar la cláusula WHERE obtengamos todos los registros menos el Seat Panda:


select *
  from VEHICULOS
 where not (ULTI_ITV between '20080101' and '20081231')
            
ID_VEHICULOMARCAMODELOPROX_ITVULTI_ITV
4CitroënC22010-08-242009-08-24

Sin embargo no ocurre así; la consulta ha devuelto los vehículos que NO pasaron la revisión durante el 2008, pero los registros con valor nulo en el campo ULTI_ITV han vuelto a ser ignorados. Esto nos obliga a extremar el cuidado con estos campos sabiendo que: cuando el motor SQL evalúa un dato nulo en una expresión de la cláusula WHERE, el motor SQL no sabe resolver la operación y considera que el resultado de dicha expresión es falso. Pero en el caso de usar IS NULL, o bien IS NOT NULL, el motor SQL sí la sabe resolver. De modo que si anteriormente se quería obtener todos los vehículos que NO pasaron la ITV durante el 2008, debe plantearse si se incluyen los vehículos que NO la han pasado nunca, y si se decide que sí, debe especificarse en la cláusula WHERE:


select *
  from VEHICULOS
 where not (ULTI_ITV between '20080101' and '20081231')
    or ULTI_ITV is null
            
ID_VEHICULOMARCAMODELOPROX_ITVULTI_ITV
1Alfa RomeoBrera2011-10-20NULL
3BMWX32010-07-18NULL
4CitroënC22010-08-242009-08-24
5FordFiesta2011-04-22NULL

Para saber que campos de una tabla pueden tomar un valor nulo, se puede pedir al SGDB una descripción de la tabla:


desc VEHICULOS
            
FIELDTYPENULLKEYDEFAULTEXTRA
ID_VEHICULOint(11)NOPRINULLauto_increment
MARCAvarchar(30)NONULL
MODELOvarchar(30)NONULL
PROX_ITVdateNONULL
ULTI_ITVdateYESNULL

En la columna NULL se informa para cada campo si permite valores nulos.


El Valor NULL en Funciones de Agregado

Para finalizar la lección retomemos algo que quedó en parte pendiente. En concreto, la función de recuento COUNT aplicada a un campo concreto. Hasta ahora solo habíamos usado COUNT(*) para el recuento de registros. Fíjese en la consulta siguiente:


select count(*) , count(ID_VEHICULO) , count(ULTI_ITV)
  from VEHICULOS
            
COUNT(*)COUNT(ID_VEHICULO)COUNT(ULTI_ITV)
552

¿Qué está devolviendo? Bueno en la primera columna lo que ya se trató en la lección 5, el recuento de registros de toda la tabla puesto que se ha omitido la cláusula WHERE. En la segunda columna, donde se hace un recuento del campo ID_VEHICULO parece que lo mismo, el número de registros de toda la tabla. Pero en la tercera columna, donde se hace el recuento del campo ULTI_ITV, el valor del recuento es dos. En realidad esta contando registros cuyo valor en el campo ULTI_ITV no es nulo, dicho de otro modo, la función de recuento COUNT aplicada a un campo, ignora los registros cuyo valor de ese campo es nulo.

Esto es extensible a las otras funciones de agregado: SUM, AVG, MAX y MIN. Los valores nulos no se pueden comparar ni sumar, no pueden intervenir en un promedio, no son valores máximos ni mínimos, son simplemente, valores nulos o indeterminados.


Resumen

El operador LIKE permite, junto a un patrón de búsqueda, hallar coincidencias dentro de una cadena. En general:

  • CADENA LIKE 'hola%' -> devuelve cierto si el valor del campo CADENA empieza por "hola"
  • CADENA LIKE '%hola' -> devuelve cierto si el valor del campo CADENA termina por "hola"
  • CADENA LIKE '%hola%' -> devuelve cierto si el valor del campo CADENA contiene la subcadena "hola"

Dependiendo del diseño de una tabla, algunos campos pueden tomar valores nulos. Cuando estos campos se condicionan en la cláusula WHERE y el motor SQL evalúa la expresión para un valor nulo, el resultado será siempre falso salvo que estemos usando el operador IS NULL o bien IS NOT NULL, en cuyo caso dependerá del caso concreto que se este evaluando.

Las funciones de agregado ignoran los valores nulos para realizar los cálculos.


Ejercicios Propuestos

  1. ¿Qué empleados se apellidan Calvo?
  2. Considerando que en la tabla VEHICULOS el campo PROX_ITV guarda la fecha de la próxima ITV que ha de pasar cada vehículo: ¿Qué vehículos que nunca han pasado la ITV deben pasar la primera revisión durante el año 2011?
Ir a la Consola

Reseñas de la lección 10

Aún no hay reseñas para esta lección. ¡Sé el primero!