Cuando LIKE no basta: búsquedas avanzadas usando RLIKE en MySQL

AUTOR: Yeray Alcala Paz

Uno de los operadores más básicos de MySQL es LIKE, que nos permite comprobar si un texto verifica un cierto patrón, gracias al uso de caracteres comodín % y _. Pero… ¿y si necesitamos algo más?

Los SGBD suelen proporcionar operadores o funciones que permiten utilizar expresiones regulares (RegExp, del inglés Regular Expression) en los patrones de búsqueda. Para la implementación de estas expresiones, la mayoría de los SGBD más conocidos se apoyan en el estándar POSIX.

Aquí nos centraremos en el caso de MySQL, que dispone del operador RLIKE (también llamado REGEXP). La sintaxis de uso de este nuevo operador es la misma que la de LIKE, pero nos permite usar expresiones regulares para construir patrones más complejos. Otros SGBD disponen de operadores o funciones similares, como el operador ~ en el caso de PostgreSQL, o la función REGEXP_LIKE en Oracle.

Nociones básicas sobre expresiones regulares

Presentamos y resumimos algunas de las nociones más básicas sobre cómo construir expresiones regulares:

  • átomo: Un carácter literal o un metacaracter.
  • metacaracteres: caracteres con un significado especial. Entre ellos...
    • . El equivalente al _ del operador LIKE
    • * El átomo que precede se puede repetir 0 o más veces. Equivalente al % en LIKE
    • + El átomo que precede se puede repetir 1 o más veces
    • {n, m} El átomo que precede se puede repetir de n a m veces.
    • ^ Indica que todo lo que precede debe ir al inicio de la linea
  • clases: Representan un conjunto predefinido de caracteres
    • [:upper:] Las letras mayúsculas
    • [:lower:] Las letras minúsculas
    • [:digit:] o [0-9] Los dígitos

En esta página web https://www.luisllamas.es/regex-introduccion/ se explica muy bien su uso y varios ejemplos, permitiendo además la exploración en su "patio de juegos".

Ejemplo 1

Supongamos que disponemos de una tabla llamada Persona, con un par de campos para el nombre y los apellidos de personas. Debemos resolver la siguiente consulta:

Nombre de las personas cuyo nombre no acabe en "A" y contenga la "I" únicamente en una posición intermedia (supondremos que no hay tildes).
MEJORABLE
SELECT concat(nombre,' ',apellidos)
FROM Persona
WHERE concat(nombre,' ',apellidos) LIKE '%I%'
  AND concat(nombre,' ',apellidos) NOT LIKE 'I%'
  AND concat(nombre,' ',apellidos) NOT LIKE '%I'
  AND concat(nombre,' ',apellidos) NOT LIKE '%A';

En este ejemplo, RLIKE nos permite juntar todas las condiciones LIKE de patrones sencillos en una sola condición de patrón más complejo.

MEJOR
SELECT concat(nombre,' ',apellidos)
FROM Persona
WHERE concat(nombre,' ',apellidos) RLIKE '^[^I].*[I].*[^IA]$';

Ejemplo 2

Supongamos que disponemos de una tabla llamada Libro, con un campo para el título de los libros de una biblioteca. Debemos resolver la siguiente consulta:

La dirección de la biblioteca requiere conocer los títulos de los libros cuyo título comience por una vocal mayúscula (supondremos que no hay tildes) y finalice con un dígito numérico.
MEJORABLE
SELECT titulo, precio
FROM libro
WHERE (titulo LIKE 'A%' OR titulo LIKE 'E%' OR titulo LIKE 'I%' OR titulo LIKE 'O%' OR titulo LIKE 'U%')
  AND (titulo LIKE '%0' OR titulo LIKE '%1' OR titulo LIKE '%2' OR titulo LIKE '%3' OR titulo LIKE '%4'
OR titulo LIKE '%5' OR titulo LIKE '%6' OR titulo LIKE '%7' OR titulo LIKE '%8' OR titulo LIKE '%9');

Esta solución no es la óptima, simplemente se usa para ejemplificar el uso de RLIKE.

MEJOR
SELECT titulo, precio 
FROM libro 
WHERE titulo RLIKE '^[AEIOU].*[0-9]$';

En este ejemplo se observa más claramente cómo el uso de expresiones regulares permite la compactación de las consultas. Por ende, en bastantes casos permitirá una mejor lectura de las consultas.

Conclusiones

En definitiva, al enfrentarnos a una verificación de patrones más compleja, el operador LIKE y sus metacaracteres son muy limitados (lo que obliga a conectar muchas condiciones). Es por ello que, a veces, para la creación de esos patrones complejos las expresiones regulares, y el operador RLIKE son muy útiles.

Una aclaración importante: compilar y verificar expresiones regulares es muy costoso por lo general, luego hay casos en los que es mejor evitar su uso. Os recomiendo leer esta página https://blog.codinghorror.com/regex-performance/.

No hay comentarios:

Publicar un comentario