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:
- Código: Seleccionar todo
select *
from EMPLEADOS
where APELLIDOS like 'R%'
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" seguida 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 cosa y acabe con una "N", por lo tanto la expresión que nos filtrará adecuadamente esto es: APELLIDOS like '%N'
- Código: Seleccionar todo
select *
from EMPLEADOS
where APELLIDOS like '%N'
En MySQL la comparación de cadenas por defecto no es sensible a mayúsculas, de ahí que aun indicando una "N" mayúscula encuentre los apellidos acabados en "n" minúscula.
Observese 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?:
- Código: Seleccionar todo
select *
from EMPLEADOS
where APELLIDOS like '%AR%'
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 que información se guarda.
Para ilustrar las particularidades del valor NULL tomemos la tabla VEHICULOS:
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?
- Código: Seleccionar todo
select *
from VEHICULOS
where ULTI_ITV is null
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:
- Código: Seleccionar todo
select *
from VEHICULOS
where ULTI_ITV is not null
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:
- Código: Seleccionar todo
select *
from VEHICULOS
where ULTI_ITV between '20080101' and '20081231'
Es de esperar entonces que al negar la cláusula WHERE obtengamos todos los registros menos el Seat Panda:
- Código: Seleccionar todo
select *
from VEHICULOS
where not (ULTI_ITV between '20080101' and '20081231')
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, 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:
- Código: Seleccionar todo
select *
from VEHICULOS
where not (ULTI_ITV between '20080101' and '20081231')
or ULTI_ITV is null
Para saber que campos de una tabla pueden tomar un valor nulo, se puede pedir al SGDB una descripción de la tabla:
- Código: Seleccionar todo
desc VEHICULOS
En la columna Null se informa para cada campo si permite valores nulos.
* * *
Para finalizar la lección retomemos algo que quedó pendiente, me refiero de la función de recuento COUNT aplicada a un campo concreto. Hasta ahora solo habíamos usado COUNT(*), fíjese en la consulta siguiente:
- Código: Seleccionar todo
select count(*) , count(ID_VEHICULO) , count(ULTI_ITV)
from VEHICULOS
¿Que 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 donde el valor de ese campo es nulo.
Esto es extensible a las otras funciones de totalización: 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.
* * *
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 cadena "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 operado IS NULL o bien IS NOT NULL, en cuyo caso dependerá del caso concreto que se este evaluando.
Las funciones de totalización ignoran el valor nulo para desarrollar los cálculos.
* * *
Ejercicio 1
¿Qué empleados se apellidan Calvo?
Ejercicio 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?