10 Lenguaje SQL: Operadores

MySQL dispone de multitud de operadores diferentes para cada uno de los tipos de columna. Esos operadores se utilizan para construir expresiones que se usan en cláusulas ORDER BY y HAVING de la sentencia SELECT y en las cláusulas WHERE de las sentencias SELECT, DELETE y UPDATE. Además se pueden emplear en sentencias SET.

Operador de asignación

En MySQL podemos crear variables y usarlas porteriormente en expresiones.

Para crear una variable hay dos posibilidades. La primera consiste en ulsar la sentencia SET de este modo:

mysql> SET @hoy = CURRENT_DATE();
Query OK, 0 rows affected (0.02 sec)

mysql> SELECT @hoy;
+------------+
| @hoy       |
+------------+
| 2005-03-23 |
+------------+
1 row in set (0.00 sec)

mysql>

La otra alternativa permite definir variables de usuario dentro de una sentencia SELECT:

mysql> SELECT @x:=10;
+--------+
| @x:=10 |
+--------+
|     10 |
+--------+
1 row in set (0.00 sec)

mysql> SELECT @x;
+------+
| @x   |
+------+
| 10   |
+------+
1 row in set (0.00 sec)

mysql>

En esta segunda forma es donde se usa el operador de asignación :=. Otros ejemplos del uso de variables de usuario pueden ser:

mysql> SELECT @fecha_min:=MIN(fecha), @fecha_max:=MAX(fecha) FROM gente;
+------------------------+------------------------+
| @fecha_min:=MIN(fecha) | @fecha_max:=MAX(fecha) |
+------------------------+------------------------+
| 1978-06-15             | 2001-12-02             |
+------------------------+------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM gente WHERE fecha=@fecha_min;
+----------+------------+
| nombre   | fecha      |
+----------+------------+
| Mengano  | 1978-06-15 |
| Pimplano | 1978-06-15 |
+----------+------------+
2 rows in set (0.00 sec)

mysql>

Una variable sin asignar será de tipo cadena y tendrá el valor NULL.

Operadores lógicos

Los operadores lógicos se usan para crear expresiones lógicas complejas. Permiten el uso de álgebra booleana, y nos ayudarán a crear condiciones mucho más precisas.

En el álgebra booleana sólo existen dos valores posibles para los operandos y los resultados: verdadero y falso. MySQL dispone de dos constantes para esos valores: TRUE y FALSE, respectivamente.

MySQL añade un tercer valor: desconocido. Esto es para que sea posible trabajar con valores NULL. El valor verdadero se implementa como 1 o TRUE, el falso como 0 o FALSE y el desconocido como NULL.

mysql> SELECT TRUE, FALSE, NULL;
+------+-------+------+
| TRUE | FALSE | NULL |
+------+-------+------+
|    1 |     0 | NULL |
+------+-------+------+
1 row in set (0.00 sec)

mysql>

Operador Y

En MySQL se puede usar tanto la forma AND como &&, es decir, ambas formas se refieren al mismo operador: Y lógico.

Se trata de un operador binario, es decir, require de dos operandos. El resultado es verdadero sólo si ambos operandos son verdaderos, y falso si cualquier operando es falso. Esto se representa mediante la siguiente tabla de verdad:

A B A AND B
falso falso falso
falso verdadero falso
verdadero falso falso
verdadero verdadero verdadero
falso NULL falso
NULL falso falso
verdadero NULL NULL
NULL verdadero NULL

Al igual que todos lo operadores binarios que veremos, el operador Y se puede asociar, es decir, se pueden crear expresiones como A AND B AND C. El hecho de que se requieran dos operandos significa que las operaciones se realizan tomando los operandos dos a dos, y estas expresiones se evalúan de izquierda a derecha. Primero se evalúa A AND B, y el resultado, R, se usa como primer operando de la siguiente operación R AND C.

mysql> SELECT 1 AND 0, 1 AND NULL, 0 AND NULL, 1 AND 0 AND 1;
+---------+------------+------------+---------------+
| 1 AND 0 | 1 AND NULL | 0 AND NULL | 1 AND 0 AND 1 |
+---------+------------+------------+---------------+
|       0 |       NULL |          0 |             0 |
+---------+------------+------------+---------------+
1 row in set (0.00 sec)

mysql>

Operador O

En MySQL este operador también tiene dos formas equivalentes OR y ||

El operador O también es binario. Si ambos operandos son distintos de NULL y el resultado es verdadero si cualquiera de ellos es verdadero, y falso si ambos son falsos. Si uno de los operandos es NULL el resultado es verdadero si el otro es verdadero, y NULL en el caso contrario. La tabla de verdad es:

A B A OR B
falso falso falso
falso verdadero verdadero
verdadero falso verdadero
verdadero verdadero verdadero
falso NULL NULL
NULL falso NULL
verdadero NULL verdadero
NULL verdadero verdadero
mysql> SELECT 1 OR 0, 1 OR NULL, 0 OR NULL, 1 OR 0 OR 1;
+--------+-----------+-----------+-------------+
| 1 OR 0 | 1 OR NULL | 0 OR NULL | 1 OR 0 OR 1 |
+--------+-----------+-----------+-------------+
|      1 |         1 |      NULL |           1 |
+--------+-----------+-----------+-------------+
1 row in set (0.00 sec)

mysql>

Operador O exclusivo

XOR también es un operador binario, que devuelve NULL si cualquiera de los operandos es NULL. Si ninguno de los operandos es NULL devolverá un valor verdadero si uno de ellos es verdadero, y falso si ambos son verdaderos o mabos falsos. La tabla de verdad será:

A B A XOR B
falso falso falso
falso verdadero verdadero
verdadero falso verdadero
verdadero verdadero falso
falso NULL NULL
NULL falso NULL
verdadero NULL NULL
NULL verdadero NULL
mysql> SELECT 1 XOR 0, 1 XOR NULL, 0 XOR NULL, 1 XOR 0 XOR 1;
+---------+------------+------------+---------------+
| 1 XOR 0 | 1 XOR NULL | 0 XOR NULL | 1 XOR 0 XOR 1 |
+---------+------------+------------+---------------+
|       1 |       NULL |       NULL |             0 |
+---------+------------+------------+---------------+
1 row in set (0.00 sec)

mysql>

Operador de negación

El operador NOT, que también se puede escribir como !, es un operador unitario, es decir sólo afecta a un operando. Si el operando es verdadero devuelve falso, y viceversa. Si el operando es NULL el valor devuelto también es NULL.

A NOT A
falso verdadero
verdadero falso
NULL NULL
mysql> SELECT NOT 0, NOT 1, NOT NULL;
+-------+-------+----------+
| NOT 0 | NOT 1 | NOT NULL |
+-------+-------+----------+
|     1 |     0 |     NULL |
+-------+-------+----------+
1 row in set (0.02 sec)

mysql>

Reglas para las comparaciones de valores

MySQL Sigue las siguientes reglas a la hora de comparar valores:

  • Si uno o los dos valores a comparar son NULL, el resultado es NULL, excepto con el operador <=>, de comparación con NULL segura.
  • Si los dos valores de la comparación son cadenas, se comparan como cadenas.
  • Si ambos valores son enteros, se comparan como enteros.
  • Los valores hexadecimales se tratan como cadenas binarias, si no se comparan con un número.
  • Si uno de los valores es del tipo TIMESTAMP o DATETIME y el otro es una constante, la constantes se convierte a timestamp antes de que se lleve a cabo la comparación. Hay que tener en cuenta que esto no se hace para los argumentos de una expresión IN(). Para estar seguro, es mejor usar siempre cadenas completas datetime/date/time strings cuando se hacen comparaciones.
  • En el resto de los casos, los valores se comparan como números en coma flotante.

Operadores de comparación

Para crear expresiones lógicas, a las que podremos aplicar el álgebra de Boole, disponemos de varios operadores de comparación. Estos operadores se aplican a cualquier tipo de columna: fechas, cadenas, números, etc, y devuelven valores lógicos: verdadero o falso (1/0).

Los operadores de comparación son los habituales en cualquier lenguaje de programación, pero además, MySQL añade varios más que resultan de mucha utilidad, ya que son de uso muy frecuente.

Operador de igualdad

El operador = compara dos expresiones, y da como resultado 1 si son iguales, o 0 si son diferentes. Ya lo hemos usado en ejemplos anteriormente:

mysql> SELECT * FROM gente WHERE fecha="2001-12-02";
+--------+------------+
| nombre | fecha      |
+--------+------------+
| Tulano | 2001-12-02 |
+--------+------------+
1 row in set (0.00 sec)

mysql>

Hay que mencionar que, al contrario que otros lenguajes, como C o C++, donde el control de tipos es muy estricto, en MySQL se pueden comparar valores de tipos diferentes, y el resultado será el esperado.

Por ejemplo:

mysql> SELECT "0" = 0, "0.1"=.1;
+---------+----------+
| "0" = 0 | "0.1"=.1 |
+---------+----------+
|       1 |        1 |
+---------+----------+
1 row in set (0.00 sec)

mysql>

Esto es así porque MySQL hace conversión de tipos de forma implícita, incluso cuando se trate de valores de tipo cadena.

Operador de igualdad con NULL seguro

El operador <=> funciona igual que el operador =, salvo que si en la comparación una o ambas de las expresiones es nula el resultado no es NULL. Si se comparan dos expresiones nulas, el resultado es verdadero:

mysql> SELECT NULL = 1, NULL = NULL;
+----------+-------------+
| NULL = 1 | NULL = NULL |
+----------+-------------+
|     NULL |        NULL |
+----------+-------------+
1 row in set (0.00 sec)

mysql> SELECT NULL <=> 1, NULL <=> NULL;
+------------+---------------+
| NULL <=> 1 | NULL <=> NULL |
+------------+---------------+
|          0 |             1 |
+------------+---------------+
1 row in set (0.00 sec)

mysql>

Operador de desigualdad

MySQL dispone de dos operadores equivalente para comprobar desigualdades, <> y !=. Si las expresiones comparadas son diferentes, el resultado es verdadero, y si son iguales, el resultado es falso:

mysql> SELECT 100 <> 32, 43 != 43;
+-----------+----------+
| 100 <> 32 | 43 != 43 |
+-----------+----------+
|         1 |        0 |
+-----------+----------+
1 row in set (0.02 sec)

mysql>

Operadores de comparación de magnitud

Disponemos de los cuatro operadores corrientes.

Operador Descripción
<= Menor o igual
< Menor
> Mayor
>= Mayor o igual

Estos operadores también permiten comparar cadenas, fechas, y por supuesto, números:

mysql> SELECT "hola" < "adios", "2004-12-31" > "2004-12-01";
+------------------+-----------------------------+
| "hola" < "adios" | "2004-12-31" > "2004-12-01" |
+------------------+-----------------------------+
|                0 |                           1 |
+------------------+-----------------------------+
1 row in set (0.00 sec)

mysql> SELECT ".01" >= "0.01", .01 >= 0.01;
+-----------------+-------------+
| ".01" >= "0.01" | .01 >= 0.01 |
+-----------------+-------------+
|               0 |           1 |
+-----------------+-------------+
1 row in set (0.00 sec)

mysql>

Cuando se comparan cadenas, se considerá menor la cadena que aparezca antes por orden alfabético.

Si son fechas, se considera que es menor cuanto más antigua sea.

Pero cuidado, como vemos en el segundo ejemplo, si comparamos cadenas que contienen números, no hay conversión, y se comparan las cadenas tal como aparecen.

Verificación de NULL

Los operadores IS NULL e IS NOT NULL sirven para verificar si una expresión determinada es o no nula. La sintaxis es:

<expresión> IS NULL
<expresión> IS NOT NULL

Por ejemplo:

mysql> SELECT NULL IS NULL;
+--------------+
| NULL IS NULL |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

mysql> SELECT "NULL" IS NOT NULL;
+--------------------+
| "NULL" IS NOT NULL |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)

mysql>

Verificar pertenencia a un rango

Entre los operadores de MySQL, hay uno para comprobar si una expresión está comprendida en un determinado rango de valores. La sintaxis es:

<expresión> BETWEEN mínimo AND máximo
<expresión> NOT BETWEEN mínimo AND máximo

En realidad es un operador prescindible, ya que se puede usar en su lugar dos expresiones de comparación y el operador AND. Estos dos ejemplos son equivalentes:

mysql> SELECT 23 BETWEEN 1 AND 100;
+----------------------+
| 23 BETWEEN 1 AND 100 |
+----------------------+
|                    1 |
+----------------------+
1 row in set (0.00 sec)

mysql> SELECT 23 >= 1 AND 23 <= 100;
+-----------------------+
| 23 >= 1 AND 23 <= 100 |
+-----------------------+
|                     1 |
+-----------------------+
1 row in set (0.00 sec)

mysql>

Del mismo modo, estas dos expresiones también lo son:

mysql> SELECT 23 NOT BETWEEN 1 AND 100;
+--------------------------+
| 23 NOT BETWEEN 1 AND 100 |
+--------------------------+
|                        0 |
+--------------------------+
1 row in set (0.00 sec)

mysql> SELECT NOT (23 BETWEEN 1 AND 100);
+----------------------------+
| NOT (23 BETWEEN 1 AND 100) |
+----------------------------+
|                          0 |
+----------------------------+
1 row in set (0.00 sec)

mysql>

Elección de no nulos

El operador COALESCE sirve para seleccionar el primer valor no nulo de una lista o conjunto de expresiones. La sintaxis es:

COALESCE(<expr1>, <expr2>, <expr3>...)

El resultado es el valor de la primera expresión distinta de NULL que aparezca en la lista. Por ejemplo:

mysql> SET @a=23, @b="abc", @d="1998-11-12";
Query OK, 0 rows affected (0.03 sec)

mysql> SELECT COALESCE(@c, @a, @b, @d);
+--------------------------+
| COALESCE(@c, @a, @b, @d) |
+--------------------------+
| 23                       |
+--------------------------+
1 row in set (0.05 sec)

mysql>

En este ejemplo no hemos definido la variable @c, por lo tanto, tal como dijimos antes, su valor se considera NULL. El operador COALESCE devuelve el valor de la primera variable no nula, es decir, el valor de @a.

Valores máximo y mínimo de una lista

Los operadores GREATEST y LEAST devuelven el valor máximo y mínimo, respectivamente, de la lista de expresiones dada. La sintaxis es:

GREATEST(<expr1>, <expr2>, <expr3>...)
LEAST(<expr1>, <expr2>, <expr3>...)

La lista de expresiones debe contener al menos dos valores.

Los argumentos se comparan según estas reglas:

  • Si el valor de retorno se usa en un contexto entero, o si todos los elementos de la lista son enteros, estos se comparan entre si como enteros.
  • Si el valor de retorno se usa en un contexto real, o si todos los elementos son valores reales, serán comparados como reales.
  • Si cualquiera de los argumentos es una cadena sensible al tipo (mayúsculas y minúsculas son caracteres diferentes), los argumentos se comparan como cadenas sensibles al tipo.
  • En cualquier otro caso, los argumentos se comparan como cadenas no sensibles al tipo.
mysql> SELECT LEAST(2,5,7,1,23,12);
+----------------------+
| LEAST(2,5,7,1,23,12) |
+----------------------+
|                    1 |
+----------------------+
1 row in set (0.69 sec)

mysql> SELECT GREATEST(2,5,7,1,23,12);
+-------------------------+
| GREATEST(2,5,7,1,23,12) |
+-------------------------+
|                      23 |
+-------------------------+
1 row in set (0.03 sec)

mysql> SELECT GREATEST(2,5,"7",1,"a",12);
+----------------------------+
| GREATEST(2,5,"7",1,"a",12) |
+----------------------------+
|                         12 |
+----------------------------+
1 row in set (0.09 sec)

mysql>

Verificar conjuntos

Los operadores IN y NOT IN sirven para averiguar si el valor de una expresión determinada está dentro de un conjunto indicado. La sintaxis es:

<expresión> IN (<expr1>, <expr2>, <expr3>...)
<expresión> NOT IN (<expr1>, <expr2>, <expr3>...)

El operador IN devuelve un valor verdadero, 1, si el valor de la expresión es igual a alguno de los valores especificados en la lista. El operador NOT IN devuelve un valor falso en el mismo caso. Por ejemplo:

mysql> SELECT 10 IN(2, 4, 6, 8, 10);
+-----------------------+
| 10 IN(2, 4, 6, 8, 10) |
+-----------------------+
|                     1 |
+-----------------------+
1 row in set (0.00 sec)

mysql>

Verificar nulos

El operador ISNULL es equivalente a IS NULL.

La sintaxis es:

ISNULL(<expresión>)

Por ejemplo:

mysql> SELECT 1/0 IS NULL, ISNULL(1/0);
+-------------+-------------+
| 1/0 IS NULL | ISNULL(1/0) |
+-------------+-------------+
|           1 |           1 |
+-------------+-------------+
1 row in set (0.02 sec)

mysql>

Encontrar intervalo

Se puede usar el operador INTERVAL para calcular el intervalo al que pertenece un valor determinado. La sintaxis es:

INTERVAL(<expresión>, <límite1>, <limite1>, ... <limiten>)

Si el valor de la expresión es menor que límite1, el operador regresa con el valor 0, si es mayor o igual que límite1 y menor que limite2, regresa con el valor 1, etc.

Todos los valores de los límites deben estar ordenados, ya que MySQL usa el algoritmo de búsqueda binaria.

Nota:

Según la documentación, los valores de los índices se trata siempre como enteros, aunque he podido verificar que el operador funciona también con valores en coma flotante, cadenas y fechas.

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

mysql> SELECT INTERVAL(@x, 0, 10, 20, 30, 40);
+---------------------------------+
| INTERVAL(@x, 0, 10, 20, 30, 40) |
+---------------------------------+
|                               2 |
+---------------------------------+
1 row in set (0.01 sec)

mysql> SELECT INTERVAL("Gerardo", "Antonio",
    -> "Fernando", "Ramón", "Xavier");
+---------------------------------------------------------------+
| INTERVAL("Gerardo", "Antonio", "Fernando", "Ramón", "Xavier") |
+---------------------------------------------------------------+
|                                                             4 |
+---------------------------------------------------------------+
1 row in set (0.01 sec)

mysql>

Operadores aritméticos

Los operadores aritméticos se aplican a valores numéricos, ya sean enteros o en coma flotante. El resultado siempre es un valor numérico, entero o en coma flotante.

MySQL dispone de los operadores aritméticos habituales: suma, resta, multiplicación y división.

En el caso de los operadores de suma, resta, cambio de signo y multiplicación, si los operandos son enteros, el resultado se calcula usando el tipo BIGINT, es decir, enteros de 64 bits. Hay que tener esto en cuenta, sobre todo en el caso de números grandes.

Operador de adición o suma

El operador para la suma es, como cabría esperar, +. No hay mucho que comentar al respecto. Por ejemplo:

mysql> SELECT 192+342, 23.54+23;
+---------+----------+
| 192+342 | 23.54+23 |
+---------+----------+
|     534 |    46.54 |
+---------+----------+
1 row in set (0.00 sec)

mysql>

Este operador, al igual que el de resta, multiplicación y división, es binario. Como comentamos al hablar de los operadores lógicos, esto no significa que no se puedan asociar, sino que la operaciones se realizan tomando los operandos dos a dos.

Operador de sustracción o resta

También con la misma lógica, el operador para restar es el -. Otro ejemplo:

mysql> SELECT 192-342, 23.54-23;
+---------+----------+
| 192-342 | 23.54-23 |
+---------+----------+
|    -150 |     0.54 |
+---------+----------+
1 row in set (0.02 sec)

mysql>

Operador unitario menos

Este operador, que también usa el símbolo -, se aplica a un único operando, y como resultado se obtiene un valor de signo contrario. Por ejemplo:

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

mysql> SELECT -@x;
+------+
| -@x  |
+------+
| -100 |
+------+
1 row in set (0.01 sec)

mysql>

Operador de producto o multiplicación

También es un operador binario, el símbolo usado es el asterisco, *. Por ejemplo:

mysql> SELECT 12343432*3123243, 312*32*12;
+------------------+-----------+
| 12343432*3123243 | 312*32*12 |
+------------------+-----------+
|   38551537589976 |    119808 |
+------------------+-----------+
1 row in set (0.00 sec)

mysql>

Operador de cociente o división

El resultado de las divisiones, por regla general, es un número en coma flotante. Por supuesto, también es un operador binario, y el símbolo usado es /.

Dividir por cero produce como resultado el valor NULL. Por ejemplo:

mysql> SELECT 2132143/3123, 4324/25434, 43/0;
+--------------+------------+------+
| 2132143/3123 | 4324/25434 | 43/0 |
+--------------+------------+------+
|       682.72 |       0.17 | NULL |
+--------------+------------+------+
1 row in set (0.00 sec)

mysql>

Operador de división entera

Existe otro operador para realizar divisiones, pero que sólo calcula la parte entera del cociente. El operador usado es DIV. Por ejemplo:

mysql> SELECT 2132143 DIV 3123, 4324 DIV 25434, 43 DIV 0;
+------------------+----------------+----------+
| 2132143 DIV 3123 | 4324 DIV 25434 | 43 DIV 0 |
+------------------+----------------+----------+
|              682 |              0 |     NULL |
+------------------+----------------+----------+
1 row in set (0.00 sec)

mysql>

Operadores de bits

Todos los operadores de bits trabajan con enteros BIGINT, es decir con 64 bits.

Los operadores son los habituales: o, y, o exclusivo, complemento y rotaciones a derecha e izquierda.

Operador de bits O

El símbolo empleado es |. Este operador es equivalente al operador OR que vimos para álgebra de Boole, pero se aplica bit a bit entre valores enteros de 64 bits.

Las tablas de verdad para estos operadores son más simples, ya que los bits no pueden tomar valores nulos:

Bit A Bit B A | B
0 0 0
0 1 1
1 0 1
1 1 1

Las operaciones con operadores de bits se realizan tomando los bits de cada operador uno a uno. Ejemplo:

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
O 00101101 11011110 100010100 11101011 11010010 11010101 00101001 11010010
  11101111 11011110 110111110 11101011 11011111 11111111 11111111 11010111

Por ejemplo:

mysql> SELECT 234 | 334, 32 | 23, 15 | 0;
+-----------+---------+--------+
| 234 | 334 | 32 | 23 | 15 | 0 |
+-----------+---------+--------+
|       494 |      55 |     15 |
+-----------+---------+--------+
1 row in set (0.00 sec)

mysql>

Operador de bits Y

El símbolo empleado es &. Este operador es equivalente al operador AND que vimos para álgebra de Boole, pero aplicado bit a bit entre valores enteros de 64 bits.

La tabla de verdad para este operador es:

Bit A Bit B A & B
0 0 0
0 1 0
1 0 0
1 1 1

Al igual que con el operador |, con el operador & las operaciones se realizan tomando los bits de cada operador uno a uno. Ejemplo:

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
Y 00101101 11011110 100010100 11101011 11010010 11010101 00101001 11010010
  00100001 11001000 000000000 11100011 00000010 10000000 00101001 00000000

Por ejemplo:

mysql> SELECT 234 & 334, 32 & 23, 15 & 0;
+-----------+---------+--------+
| 234 & 334 | 32 & 23 | 15 & 0 |
+-----------+---------+--------+
|        74 |       0 |      0 |
+-----------+---------+--------+
1 row in set (0.00 sec)

mysql>

Operador de bits O exclusivo

El símbolo empleado es ^. Este operador es equivalente al operador XOR que vimos para álgebra de Boole, pero aplicado bit a bit entre valores enteros de 64 bits.

La tabla de verdad para este operador es:

Bit A Bit B A ^ B
0 0 0
0 1 1
1 0 1
1 1 0

Al igual que con los operadores anteriores, con el operador ^ las operaciones se realizan tomando los bits de cada operador uno a uno. Ejemplo:

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
^ 00101101 11011110 100010100 11101011 11010010 11010101 00101001 11010010
  11001110 00010100 110111110 00001000 11011101 01111111 11010110 11010111

Por ejemplo:

mysql> SELECT 234 ^ 334, 32 ^ 23, 15 ^ 0;
+-----------+---------+--------+
| 234 ^ 334 | 32 ^ 23 | 15 ^ 0 |
+-----------+---------+--------+
|       420 |      55 |     15 |
+-----------+---------+--------+
1 row in set (0.00 sec)

mysql>

Operador de bits de complemento

El símbolo empleado es ~. Este operador es equivalente al operador NOT que vimos para álgebra de Boole, pero aplicado bit a bit entre valores enteros de 64 bits.

Se trata de un operador unitario, y la tabla de verdad es:

Bit A ~A
0 1
1 0

Al igual que con los operadores anteriores, con el operador ~ las operaciones se realizan tomando los bits del operador uno a uno. Ejemplo:

~ 11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
  00011100 00110101 101010101 00011100 11110000 01010101 00000000 11111010

Por ejemplo:

mysql> SELECT ~234, ~32, ~15;
+----------------------+----------------------+----------------------+
| ~234                 | ~32                  | ~15                  |
+----------------------+----------------------+----------------------+
| 18446744073709551381 | 18446744073709551583 | 18446744073709551600 |
+----------------------+----------------------+----------------------+
1 row in set (0.00 sec)

mysql>

Como vemos en el ejemplo, el resultado de aplicar el operador de complemento no es un número negativo. Esto es porque si no se especifica lo contrario, se usan valores BIGINT sin signo.

Si se fuerza un tipo, el resultado sí será un número de signo contrario. Por ejemplo:

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

mysql> SELECT @x;
+------+
| @x   |
+------+
| -2   |
+------+
1 row in set (0.00 sec)

mysql>

Para los que no estén familiarizados con el álgebra binaria, diremos que para consegir el negativo de un número no basta con calcular su complemento. Además hay que sumar al resultado una unidad:

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

mysql> SELECT @x + @y;
+---------+
| @x + @y |
+---------+
|       0 |
+---------+
1 row in set (0.00 sec)

mysql>

Operador de desplazamiento a la izquierda

El símbolo empleado es <<. Se trata de un operador binario. El resultado es que los bits del primer operando se desplazan a la izquieda tantos bits como indique el segundo operando. Por la derecha se introducen otros tantos bits con valor 0. Los bits de la parte izquierda que no caben en los 64 bits, se pierden.

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
<< 12
  10100101 010101110 00110000 11111010 10101111 11110000 01010000 00000000

El resultado, siempre que no se pierdan bits por la izquierda, equivale a multiplicar el primer operando por dos para cada desplazamiento.

Por ejemplo:

mysql> SELECT 234 << 25, 32 << 5, 15 << 1;
+------------+---------+---------+
| 234 << 25  | 32 << 5 | 15 << 1 |
+------------+---------+---------+
| 7851737088 |    1024 |      30 |
+------------+---------+---------+
1 row in set (0.00 sec)

mysql>

Operador de desplazamiento a la derecha

El símbolo empleado es >>. Se trata de un operador binario. El resultado es que los bits del primer operando se desplazan a la derecha tantos bits como indique el segundo operando. Por la izquieda se introducen otros tantos bits con valor 0. Los bits de la parte derecha que no caben en los 64 bits, se pierden.

  11100011 11001010 010101010 11100011 00001111 10101010 11111111 00000101
>> 7
  00000001 11000111 10010100 101010101 11000110 00011111 01010101 11111110

El resultado equivale a dividir el primer operando por dos para cada desplazamiento.

Por ejemplo:

mysql> SELECT 234 >> 25, 32 >> 5, 15 >> 1;
+-----------+---------+---------+
| 234 >> 25 | 32 >> 5 | 15 >> 1 |
+-----------+---------+---------+
|         0 |       1 |       7 |
+-----------+---------+---------+
1 row in set (0.00 sec)

mysql>

Contar bits

El último operador de bits del que dispone MySQL es BIT_COUNT(). Este operador devuelve el número de bits iguales a 1 que contiene el argumento especificado. Por ejemplo:

mysql> SELECT BIT_COUNT(15), BIT_COUNT(12);
+---------------+---------------+
| BIT_COUNT(15) | BIT_COUNT(12) |
+---------------+---------------+
|             4 |             2 |
+---------------+---------------+
1 row in set (0.00 sec)

mysql>

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>