Introducción
Esta es la tercera parte de unos posts que vengo escribiendo sobre ejercicios propuestos de MySQL. Ahora veremos cómo combinar algunas funciones que vimos en los otros tutoriales. Son pocos, pero al principio son difíciles.
Ejercicios con solución
Tabla
Recordemos que vamos a estar utilizando esta tabla para todos los ejercicios:
/*
Si no tienes una base de datos, copia las siguientes dos líneas que no están comentadas
*/
CREATE DATABASE IF NOT EXISTS pruebas;
USE pruebas;
/*
Si ya tienes una base de datos, sólo copia lo siguiente
*/
CREATE TABLE tblUsuarios (
idx INT PRIMARY KEY AUTO_INCREMENT,
usuario VARCHAR(20),
nombre VARCHAR(20),
sexo VARCHAR(1),
nivel TINYINT,
email VARCHAR(50),
telefono VARCHAR(20),
marca VARCHAR(20),
compañia VARCHAR(20),
saldo FLOAT,
activo BOOLEAN
);
INSERT INTO tblUsuarios
VALUES
('1','BRE2271','BRENDA','M','2','brenda@live.com','655-330-5736','SAMSUNG','IUSACELL','100','1'),
('2','OSC4677','OSCAR','H','3','oscar@gmail.com','655-143-4181','LG','TELCEL','0','1'),
('3','JOS7086','JOSE RAÚL','H','3','francisco@gmail.com','655-143-3922','NOKIA','MOVISTAR','150','1'),
('4','LUI6115','LUIS FRANCISCO','H','0','enrique@outlook.com','655-137-1279','SAMSUNG','TELCEL','50','1'),
('5','LUI7072','LUIS','H','1','luis@hotmail.com','655-100-8260','NOKIA','IUSACELL','50','0'),
('6','DAN2832','DANIEL ALDAIR','H','0','daniel@outlook.com','655-145-2586','SONY','UNEFON','100','1'),
('7','JAQ5351','JAQUELINE','M','0','jaqueline@outlook.com','655-330-5514','BLACKBERRY','AXEL','0','1'),
('8','ROM6520','ROMAN','H','2','roman@gmail.com','655-330-3263','LG','IUSACELL','50','1'),
('9','BLA9739','BLAS','H','0','blas@hotmail.com','655-330-3871','LG','UNEFON','100','1'),
('10','JES4752','JESSICA','M','1','jessica@hotmail.com','655-143-6861','SAMSUNG','TELCEL','500','1'),
('11','DIA6570','DIANA LAURA','M','1','diana@live.com','655-143-3952','SONY','UNEFON','100','0'),
('12','RIC8283','RICARDO','H','2','ricardo@hotmail.com','655-145-6049','MOTOROLA','IUSACELL','150','1'),
('13','VAL6882','VALENTINA','M','0','valentina@live.com','655-137-4253','BLACKBERRY','AT&T','50','0'),
('14','BRE8106','BRENDA','M','3','brenda2@gmail.com','655-100-1351','MOTOROLA','NEXTEL','150','1'),
('15','LUC4982','LUCIA','M','3','lucia@gmail.com','655-145-4992','BLACKBERRY','IUSACELL','0','1'),
('16','JUA2337','JUAN JOSÉ','H','0','juan@outlook.com','655-100-6517','SAMSUNG','AXEL','0','0'),
('17','ELP2984','ELPIDIO','H','1','elpidio@outlook.com','655-145-9938','MOTOROLA','MOVISTAR','500','1'),
('18','JES9640','JESSICA','M','3','jessica2@live.com','655-330-5143','SONY','IUSACELL','200','1'),
('19','LET4015','LETICIA','M','2','leticia@yahoo.com','655-143-4019','BLACKBERRY','UNEFON','100','1'),
('20','LUI1076','LUIS','H','3','luis2@live.com','655-100-5085','SONY','UNEFON','150','1'),
('21','HUG5441','HUGO','H','2','hugo@live.com','655-137-3935','MOTOROLA','AT&T','500','1');
Nota: no es la misma tabla que antes, ya que a ésta la hemos modificado de tal manera que a algunos usuarios se les asignó un segundo nombre, mismo que será de utilidad para los ejercicios.
Una vez dicho eso, vamos allá.
Listar el primer nombre de todos los usuarios
Seleccionar el primer nombre de los usuarios. En caso de que tengan sólo un nombre lo seleccionamos. En caso de que tengan dos, seleccionamos el primero. Casos de uso:
JOSE RAÚL => JOSE
OSCAR => OSCAR
Solución
SELECT
IF(
INSTR(nombre, ' ') <> 0, #Condición
LEFT(nombre, INSTR(nombre, ' ')), # En caso de que se cumpla, lo cortamos
nombre # En caso de que no se cumpla, lo seleccionamos como está
)
AS primerNombre
FROM tblUsuarios;
Utilizamos INSTR, que devuelve la posición que tiene una subcadena dentro de una cadena. Recordemos que si dicha subcadena no se encuentra, el resultado al llamar la función es 0. Sabiendo esto, utilizamos IF para ver si la posición es 0.
Si la posición es 0, significa que no había espacios; es decir, que la persona sólo tiene un nombre. En caso de que no sea 0, cortamos la cadena con LEFT.
Listar el segundo nombre de los usuarios, y listar el primero en caso de que no lo tengan
Ahora hagamos lo contrario si así se le puede llamar. Listar el segundo nombre del usuario en caso de que éste tenga, y si no, pues listamos sólo el primero. Los casos de uso:
JOSE RAÚL => RAÚL
OSCAR => OSCAR
PD: ya sé que JOSÉ lleva acento pero así estaba en la base de datos y me dio pereza arreglarlo; además, no afecta.
Rápidamente nuestra mente nos traicionará y dirá: cambia sólo LEFT por RIGHT en la consulta anterior, y listo.
Pero no, no es así. Esto requiere un poco más de concentración. Si sólo cortamos con RIGHT desde donde está el espacio, cortará la cadena “invertida” y nos dará un nombre como “E RAÚL” (suponiendo que es JOSE RAÚL).
Recordemos que LEFT funcionó porque comienza a contar caracteres al igual que INSTR. Es decir, ambos cuentan desde la izquierda. Así que si usamos el mismo índice para ambos todo irá bien. En cambio, RIGHT comienza a contar desde la derecha.
La solución es simple, utilizamos RIGHT pero lo combinamos con CHAR_LENGTH para que reste la posición del índice.
Queda así:
SELECT
IF(
INSTR(nombre, ' ') <> 0, #Condición
RIGHT(nombre, CHAR_LENGTH(nombre) - INSTR(nombre, ' ')), # En caso de que se cumpla, lo cortamos
nombre # En caso de que no se cumpla, lo seleccionamos como está
)
AS segundoNombre
FROM tblUsuarios;
Otra solución
La solución que utiliza RIGHT con CHAR_LENGTH fue la que se me ocurrió a mí, pero siempre hay muchas formas de hacer las cosas. Un amigo lo hizo con MID y a mi parecer quedó más elegante. Aquí dejo la consulta:
SELECT
IF(
INSTR(nombre, ' ') <> 0,
MID(
nombre,
INSTR(nombre, ' ') + 1, #Sumar 1, por el espacio
CHAR_LENGTH(nombre) - INSTR(nombre, " ")
),
nombre
)
AS segundoNombre
FROM tblUsuarios;
Listar los nombres de los usuarios que comiencen con una letra vocal
SELECT nombre FROM tblUsuarios WHERE nombre LIKE "A%" OR nombre LIKE "E%" OR nombre LIKE "I%" OR nombre LIKE "O%" OR nombre LIKE "U%";
Para esto utilizamos LIKE y el comodín %, dicho comodín quiere decir “cualquier cosa” así que con que comiencen con A, E, I, O, U y terminen con lo que sea estarán bien.
Listar los nombres de los usuarios que finalicen con una letra vocal
SELECT nombre FROM tblUsuarios WHERE nombre LIKE "%A" OR nombre LIKE "%E" OR nombre LIKE "%I" OR nombre LIKE "%O" OR nombre LIKE "%U";
Utilizamos de nuevo el comodín % pero ahora al revés, de manera que al principio tengan cualquier cosa pero que siempre terminen con alguna vocal.
Listar los nombres de los usuarios que tengan la letra A u O intermedias
SELECT nombre FROM tblUsuarios WHERE nombre LIKE "%A%" OR nombre LIKE "%O%";
Ahora utilizamos el comodín pero 2 veces, así: %%. De esta forma indicamos que pueden tener lo que sea a la izquierda así como a la derecha, mientras tengan la letra mencionada en alguna parte del centro.
Listar los nombres de los usuarios que no utilicen correo electrónico de Microsoft (Outlook, Hotmail, live)
SELECT email FROM tblUsuarios WHERE email NOT LIKE "%@hotmail%" AND email NOT LIKE "%@outlook%" AND email NOT LIKE "%@live%";
Para terminar, usamos un NOT combinado con LIKE. Los utilizamos 3 veces para descartar opciones de outlook, hotmail y live.
Conclusión
Con esos ejercicios terminamos hoy.
Aquí hay más:
Ejercicios resueltos de consultas con MySQL
Ejercicios resueltos con MySQL: Funciones de cadena, UPDATE y DELETE
de gran ayuda muchas gracias