Operadores de control de flujo

En MySQL no siempre es sencillo distinguir los operadores de las funciones. En el caso del control de flujo sólo veremos un operador, el CASE. El resto los veremos en el capítulo de funciones.

Operador CASE

Existen dos sintaxis alternativas para CASE:

CASE valor WHEN [valor1] THEN resultado1 [WHEN [valori] THEN resultadoi ...] [ELSE resultado] END 
CASE WHEN [condición1] THEN resultado1 [WHEN [condicióni] THEN resultadoi ...] [ELSE resultado] END

La primera forma devuelve el resultado para el valori que coincida con valor.

La segunda forma devuelve el resultado para la primera condición verdadera.

Si no hay coincidencias, se devuelve el valor asociado al ELSE, o NULL si no hay parte ELSE.

mysql> SET @x=1;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT CASE @x WHEN 1 THEN "uno"
    -> WHEN 2 THEN "varios"
    -> ELSE "muchos" END\G
*************************** 1. row ***************************
CASE @x WHEN 1 THEN "uno"
WHEN 2 THEN "varios"
ELSE "muchos" END: uno
1 row in set (0.02 sec)

mysql> SET @x=2;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT CASE WHEN @x=1 THEN "uno"
    -> WHEN @x=2 THEN "varios"
    -> ELSE "muchos" END\G
*************************** 1. row ***************************
CASE WHEN @x=1 THEN "uno"
WHEN @x=2 THEN "varios"
ELSE "muchos" END: varios
1 row in set (0.00 sec)

mysql>

Operadores para cadenas

MySQL dispone de varios operadores para comparación de cadenas, con patrones y con expresiones regulares.

Operador LIKE

El operador LIKE se usa para hacer comparaciones entre cadenas y patrones. El resultado es verdadero (1) si la cadena se ajusta al patrón, y falso (0) en caso contrario. Tanto si la cadena como el patrón son NULL, el resultado es NULL. La sintaxis es:

<expresión> LIKE <patrón> [ESCAPE 'carácter_escape']

Los patrones son cadenas de caracteres en las que pueden aparecer, en cualquier posición, los caracteres especiales '%' y '_'. El significado de esos caracteres se puede ver en la tabla siguiente:

Carácter Descripción
% Coincidencia con cualquier número de caracteres, incluso ninguno.
_ Coincidencia con un único carácter.

Por ejemplo:

mysql> SELECT "hola" LIKE "_o%";
+-------------------+
| "hola" LIKE "_o%" |
+-------------------+
|                 1 |
+-------------------+
1 row in set (0.00 sec)

mysql>

La cadena "hola" se ajusta a "_o%", ya que el carácter 'h' se ajusta a la parte '_' del patrón, y la subcadena "la" a la parte '%'.

La comparación es independiente del tipo de los caracteres, es decir, LIKE no distingue mayúsculas de minúsculas, salvo que se indique lo contrario (ver operadores de casting):

mysql> SELECT "hola" LIKE "HOLA";
+--------------------+
| "hola" LIKE "HOLA" |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.01 sec)

mysql>

Como siempre que se usan caracteres concretos para crear patrones, se presenta la dificultad de hacer comparaciones cuando se deben buscar precisamente esos caracteres concretos. Esta dificultad se suele superar mediante secuencias de escape. Si no se especifica nada en contra, el carácter que se usa para escapar es '\'. De este modo, si queremos que nuestro patrón contenga los caracteres '%' o '_', los escaparemos de este modo: '\%' y '\_':

mysql> SELECT "%_%" LIKE "_\_\%";
+--------------------+
| "%_%" LIKE "_\_\%" |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)

mysql>

Pero MySQL nos permite usar otros caracteres para crear secuencias de escape, para eso se usa la cláusula opcional ESCAPE:

mysql> SELECT "%_%" LIKE "_!_!%" ESCAPE '!';
+-------------------------------+
| "%_%" LIKE "_!_!%" ESCAPE '!' |
+-------------------------------+
|                             1 |
+-------------------------------+
1 row in set (0.00 sec)

mysql>

En MySQL, LIKE también funciona con expresiones numéricas. (Esto es una extensión a SQL.)

mysql> SELECT 1450 LIKE "1%0";
+-----------------+
| 1450 LIKE "1%0" |
+-----------------+
|               1 |
+-----------------+
1 row in set (0.00 sec)

mysql>

El carácter de escape no se aplica sólo a los caracteres '%' y '_'. MySQL usa la misma sintaxis que C para las cadenas, de modo que los caracteres como '\n', '\r', etc también son secuencias de escape, y si se quieren usar como literales, será necesario escaparlos también.

Operador NOT LIKE

La sintaxis es:

<expresión> NOT LIKE <patrón> [ESCAPE 'carácter_escape']

Equivale a:

NOT (<expresión> LIKE <patrón> [ESCAPE 'carácter_escape'])

Operadores REGEXP y RLIKE

La sintaxis es:

<expresión> RLIKE <patrón>
<expresión> REGEXP <patrón>

Al igual que LIKE el operador REGEXP (y su equivalente RLIKE), comparan una expresión con un patrón, pero en este caso, el patrón puede ser una expresión regular extendida.

El valor de retorno es verdadero (1) si la expresión coincide con el patrón, en caso contrario devuelve un valor falso (0). Tanto si la expresión como el patrón son nulos, el resultado es NULL.

El patrón no tiene que ser necesariamente una cadena, puede ser una expresión o una columna de una tabla.

mysql> SELECT 'a' REGEXP '^[a-d]';
+---------------------+
| 'a' REGEXP '^[a-d]' |
+---------------------+
|                   1 |
+---------------------+
1 row in set (0.08 sec)

mysql>

Operadores NOT REGEXP y NOT RLIKE

La sintaxis es:

<expresión> NOT RLIKE <patrón>
<expresión> NOT REGEXP <patrón>

Que equivalen a:

NOT (<expresión> REGEXP <patrón>)

Operadores de casting

En realidad sólo hay un operador de casting: BINARY.

Operador BINARY

El operador BINARY convierte una cadena de caracteres en una cadena binaria.

Si se aplica a una cadena que forma parte de una comparación, esta se hará de forma sensible al tipo, es decir, se distinguirán mayúsculas de minúsculas.

También hace que los espacios al final de la cadena se tengan en cuenta en la comparación.

mysql> SELECT 'a' = 'A', 'a' = BINARY 'A';
+-----------+------------------+
| 'a' = 'A' | 'a' = BINARY 'A' |
+-----------+------------------+
|         1 |                0 |
+-----------+------------------+
1 row in set (0.03 sec)

mysql> SELECT 'a' = 'a ', 'a' = BINARY 'a ';
+------------+-------------------+
| 'a' = 'a ' | 'a' = BINARY 'a ' |
+------------+-------------------+
|          1 |                 0 |
+------------+-------------------+
1 row in set (0.00 sec)

mysql>

Cuando se usa en comparaciones, BINARY afecta a la comparación en conjunto, es indiferente que se aplique a cualquiera de las dos cadenas.

Tabla de precedencia de operadores

Las precedencias de los operadores son las que se muestran en la siguiente tabla, empezando por la menor:

Operador
:=
||, OR, XOR
&&, AND
NOT
BETWEEN, CASE, WHEN, THEN, ELSE
=, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
|
&
<<, >>
-, +
*, /, DIV, %, MOD
^
- (unitario), ~ (complemento)
!
BINARY, COLLATE

Paréntesis

Como en cualquier otro lenguaje, los paréntesis se pueden usar para forzar el orden de la evaluación de determinadas operaciones dentro de una expresión. Cualquier expresión entre paréntesis adquiere mayor precedencia que el resto de las operaciones en el mismo nivel de paréntesis.

mysql> SELECT 10+5*2, (10+5)*2;
+--------+----------+
| 10+5*2 | (10+5)*2 |
+--------+----------+
|     20 |       30 |
+--------+----------+
1 row in set (0.00 sec)

mysql>