Actividad Progresiva SQL — Subiendo de Nivel
Esta actividad fue creada por Robinson Andres Cortes
En esta actividad explorarás consultas SQL a través de un conjunto de ejercicios de investigación. Intenta completar la actividad usando únicamente W3Schools, w3resource o SQLhabit como referencia.
Copia y pega el código proporcionado en tu DBMS de SQL preferido. Aunque los ejercicios funcionan con cualquier motor SQL, la solución de ejemplo utiliza MySQL.
No repetimos consultas que hagan exactamente lo mismo.
Cada paso añade una capa nueva de razonamiento.
Cuando alguien termina el Nivel 5 sin copiar, ya no está aprendiendo SQL.
Está aprendiendo a pensar en datos.
Nivel 1 — Fundamentos (Exploración básica)
-
Listar todos los usuarios.
Verificar si estoy en lo correcto
En este ejercicio, necesitamos seleccionar todos los datos de la tabla en la base de datos que creamos. En este caso, la tabla se llama
users.
En SQL del mundo real, esta solución no difiere mucho de lo que verás en la práctica. El concepto clave aquí es que el operador*significa todas las columnas.Con esto en mente, aquí está la solución:
SELECT * FROM users -
Mostrar solo
first_name,last_nameyemail.Revelar la verdad
En este ejercicio, continuamos con la misma lógica del anterior. El único cambio son las columnas seleccionadas.
En lugar de seleccionar todas las columnas (*), ahora solo necesitamos obtenerfirst_name,last_nameyemail.Con esto en mente, aquí está la solución:
SELECT first_name, last_name, email FROM users -
Filtrar usuarios cuyo
rolesea'admin'.Muéstrame la magia
En este ejercicio, introducimos otro concepto de SQL llamado
WHERE.
Esta es una sentencia condicional que filtra los datos: solo se mostrarán las filas que cumplan con la condición dada:SELECT * FROM users WHERE role = 'admin' -
Filtrar usuarios con
document_type = 'CC'.Momento de la verdad
Este sigue el ejercicio anterior, pero ahora no estamos preguntando por el
role.
En su lugar, estamos buscando eldocument_type:SELECT * FROM users WHERE document_type = 'CC' -
Mostrar usuarios mayores de 18 años (calcular la edad desde
birth_date).¿Lo hice bien?
Para resolver este reto, necesitamos introducir la función
TIMESTAMPDIFF().
En MySQL,TIMESTAMPDIFF()es una función poderosa que se utiliza para calcular la diferencia entre dos valoresDATEoDATETIME.En este caso, convertimos
birth_datea años comparándolo con la fecha actual, y luego verificamos si el usuario es mayor de 18 años.El ejercicio podría verse así:
SELECT * FROM users WHERE TIMESTAMPDIFF(YEAR, birth_date , CURDATE()) > 18Más información sobre
TIMESTAMPDIFF()aquí -
Mostrar usuarios cuyo ingreso sea mayor a 5,000,000.
Haz clic para spoilers
Siguiendo la misma lógica del ejercicio anterior, podemos usar el símbolo
>(mayor que).
Debemos asegurarnos de quemonthly_incomesea mayor que5000000.Con esto en mente, aquí está la solución:
SELECT * FROM users WHERE monthly_income > 5000000 -
Mostrar usuarios cuyo nombre comience con "A".
Veamos…
Para resolver este ejercicio, debo presentarte un nuevo concepto llamado el operador
LIKE.
El operadorLIKEse utiliza en una cláusulaWHEREpara buscar un patrón específico en una columna.
Para devolver registros que comiencen con una letra o frase específica, se agrega el%al final de la letra o frase.El ejercicio podría verse así:
SELECT * FROM users WHERE first_name like 'a%'Más información sobre el operador
LIKEaquí -
Mostrar usuarios que no tengan
company.Clic arriesgado
Para resolver este reto, primero debemos entender que un usuario sin empresa tiene
company = NULL.Para esto, introducimos un nuevo concepto de SQL: el operador
IS.
El operadorISse utiliza para comparar un valor conNULLo con valores booleanos (TRUE,FALSE). Es especialmente importante porqueNULLno se puede comparar usando el operador=.Con esto en mente, aquí está la solución:
SELECT * FROM users WHERE company IS NULLMás información sobre el operador
ISaquí
Aquí ya aprendiste SELECT, WHERE, operadores lógicos y NULL.
Nivel 2 — Combinación de condiciones
-
Usuarios mayores de 25 años que sean
'employee'.Respuesta, por favor
En este ejercicio introducimos algunos nuevos operadores de SQL. El primero es
AND.El operador
ANDes un operador lógico que devuelveTRUEsolo si ambas condiciones sonTRUE.
En este caso, la condición seráTRUEsi el usuario es mayor de 25 años y tiene empleo.Otro concepto importante es el operador
NOT.
El operadorNOTtambién es un operador lógico que devuelveTRUEcuando una condición no se cumple.
En este caso, sicompanyno esNULL, la condición devolveráTRUE.Con esto en mente, aquí está la solución:
SELECT * FROM users WHERE TIMESTAMPDIFF(YEAR, birth_date , CURDATE()) > 25 AND company IS NOT NULLMás información sobre el operador
ANDaquí.
Más información sobre el operadorNOTaquí. -
Usuarios con
'CC'que estén activos.¿Soy un genio?
Siguiendo el ejercicio anterior, solo necesitamos verificar que
document_type='CC'yis_active=1:SELECT * FROM users WHERE document_type = 'CC' AND is_active = 1 -
Usuarios mayores de edad sin empleo.
¿O no…?
Este ejercicio es similar al ejercicio 9, pero filtra usuarios mayores de 18 años, que es la mayoría de edad en mi país.
SELECT * FROM users WHERE TIMESTAMPDIFF(YEAR, birth_date , CURDATE()) > 17 AND company IS NULL -
Usuarios con empleo y con ingresos mayores a 3,000,000.
Hora de confesar
Primero, verificamos que el usuario tenga empleo.
Esto significa que la columnacompanyno debe serNULL.Luego, filtramos los usuarios cuyo ingreso sea mayor a 3,000,000 usando el operador de comparación
>.
Ambas condiciones deben cumplirse para que el usuario aparezca en el resultado.Teniendo esto en cuenta, aquí está la solución:
SELECT * FROM users WHERE company IS NOT NULL AND monthly_income > 3000000 -
Usuarios casados con al menos 1 hijo.
Mostrar la respuesta
Primero, verificamos el estado civil comparando la columna
marital_statuscon el valor'Casado'.
Luego, nos aseguramos de que el usuario tenga al menos un hijo comprobando quechildren_countsea mayor o igual a1.Ambas condiciones deben cumplirse para que el usuario sea incluido en el resultado.
SELECT * FROM users WHERE marital_status = 'Casado' AND children_count >= 1 -
Usuarios entre 30 y 40 años.
Prueba o dolor
En este caso, primero verificamos que la edad del usuario sea mayor o igual a 30 y menor o igual a 40.
Esto hace que el resultado esté entre los 30 y 40 años.SELECT * FROM users WHERE TIMESTAMPDIFF(YEAR, birth_date , CURDATE()) >= 30 AND TIMESTAMPDIFF(YEAR, birth_date , CURDATE()) <= 40 -
Usuarios
'admin'verificados mayores de 25 años.Júzgame
Primero debemos asegurarnos de que el rol del usuario sea
adminy que sea mayor de 25 años.SELECT * FROM users WHERE role = 'admin' AND TIMESTAMPDIFF(YEAR, birth_date , CURDATE()) > 25
Aquí combinamos múltiples condiciones y lógica booleana.
Nivel 3 — Introducción a análisis (Agregaciones)
-
Contar usuarios por
role.Chequeo de realidad
Para comenzar esta sección, necesitamos introducir algunos conceptos nuevos que nos ayudarán a resolver este reto.
El primer concepto es la función
COUNT().
La funciónCOUNT()se utiliza para contar el número de filas que coinciden con una condición específica.El segundo concepto es la sentencia
GROUP BY.
Esta agrupa filas que tienen los mismos valores en filas de resumen.El último concepto es la palabra clave
AS, que se utiliza para renombrar una columna o tabla usando un alias.Suficiente teoría — pongamos las manos en el teclado.
Primero, necesitamos hacer un
SELECTde los datos que queremos analizar. En este caso, seleccionamos la columnaroley el número de veces que aparece cada rol usandoCOUNT(role).
En lugar de mostrar el nombre de columna por defectoCOUNT(role), usamos la palabra claveASpara darle un alias más legible.Luego, especificamos la tabla donde están almacenados los datos y finalmente usamos
GROUP BYpara agrupar los resultados por rol.SELECT role, COUNT(role) AS Counting FROM users GROUP BY roleMás información sobre la función
COUNT()aquí.
Más información sobre la sentenciaGROUP BYaquí.
Más información sobre la palabra claveASaquí. -
Contar usuarios por
document_type.No te rías
Este ejercicio es muy similar al anterior. En este caso, usamos
document_typecomo el campo de agrupación.SELECT document_type, COUNT(document_type) AS Counting FROM users GROUP BY document_type -
Contar cuántos usuarios están desempleados.
Sé amable
En este caso tomamos
'Unemployed'como un valor fijo y usamosCOUNT(*)para contar todos los usuarios en la tablausers.
Luego filtramos solo los usuariosWHERE company IS NULL, lo que significa que están desempleados.SELECT 'Unemployed', COUNT(*) AS Counting FROM users WHERE company IS NULL -
Calcular el promedio general de ingresos.
Haz clic con cuidado
Para este ejercicio, necesitamos introducir un par de conceptos nuevos de SQL.
El primero es la función
AVG().
La funciónAVG()devuelve el valor promedio de una columna numérica.El segundo y último concepto de esta sección es la función
ROUND().
La funciónROUND()redondea un número a una cantidad específica de decimales.En este caso, queremos calcular el ingreso mensual promedio de todos los usuarios.
Usamos la funciónAVG()para obtener el promedio y la funciónROUND()para redondear el resultado a 0 decimales.Este es el resultado final:
SELECT 'Average Income', ROUND(AVG(monthly_income ), 0) FROM usersMás información sobre la función
AVG()aquí.
Más información sobre la funciónROUND()aquí. -
Calcular el promedio de ingresos por
role.La gran revelación
Este ejercicio es muy similar al anterior, pero en este caso agrupamos los resultados usando
GROUP BY role.SELECT role, ROUND(AVG(monthly_income ), 0) AS average_income FROM users GROUP BY role
Ahora ya no estás consultando individuos, estás leyendo patrones.
Nivel 4 — Pensamiento analítico
-
Mostrar profesiones con más de 10 personas.
¿Estuve cerca?
En este ejercicio reunimos varios conceptos. Primero, introducimos un nuevo tema de SQL llamado
HAVING.La cláusula
HAVINGfunciona de manera similar aWHERE, pero con una diferencia importante:
la cláusulaWHEREno puede usarse con funciones de agregación, mientras queHAVINGsí.Nuestro objetivo es mostrar todas las profesiones de los usuarios, contar cuántos usuarios pertenecen a cada profesión, asignar un alias a ese conteo, agrupar los resultados por profesión y finalmente filtrar aquellas profesiones que tengan más de 10 usuarios.
Con esto en mente, aquí está la solución:
SELECT profession, COUNT(*) AS profession_count FROM users GROUP BY profession HAVING profession_count > 10Más información sobre
HAVINGaquí. -
Mostrar la ciudad con más usuarios.
Respuesta desbloqueada
En esta sección empieza lo divertido, porque ahora debemos usar algunos conceptos que son realmente útiles en el campo.
El primer concepto que veremos se llama la palabra clave
ORDER BY. Esta palabra clave se utiliza para ordenar los elementos de una forma específica, ya sea ascendente (ASC) o descendente (DESC); en este caso vamos a usarDESC.Otra herramienta importante es
LIMIT. Esta cláusula limita los resultados a la cantidad que especifiquemos; en este caso solo necesitamos el primer resultado.Teniendo todo esto en cuenta, esta es la solución:
SELECT city, COUNT(*) AS city_count FROM users GROUP BY city ORDER BY city_count DESC LIMIT 1Más información sobre la palabra clave
ORDER BYaquí.
Más información sobreLIMITaquí. -
Comparar la cantidad de menores vs mayores de edad.
Sin trampas
Es momento de presentarles un nuevo concepto increíble: la función
SUM().
La funciónSUM()devuelve la suma de una columna numérica. Si dentro de la función hay una expresión booleana y esta devuelveTRUE, entonces suma1.
Si devuelveFALSE, entonces suma0.En este caso se vería así:
SELECT
SUM(TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) > 17) AS adults,
SUM(TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) < 18) AS minors
FROM usersMás información sobre la función
SUM()aquí. -
Promedio de ingresos por ciudad, ordenado de mayor a menor.
Vamos a descubrirlo
Otro excelente ejercicio para practicar múltiples conceptos de SQL al mismo tiempo.
En este ejercicio, primero calculamos el promedio de
monthly_incomepara cada ciudad.
Luego, redondeamos ese valor y le asignamos un alias.
Después, agrupamos los resultados por ciudad y finalmente los ordenamos pormonthly_incomede forma descendente.Con todo esto en mente, aquí está la solución:
SELECT city, ROUND(AVG(monthly_income )) AS income_city FROM users GROUP BY city ORDER BY income_city DESC -
Mostrar las 5 personas con mayor ingreso.
Redoble de tambores…
Si has completado los ejercicios anteriores en orden, este debería ser extremadamente fácil.
Primero, seleccionamos las columnas
first_nameymonthly_income.
Luego, ordenamos los resultados pormonthly_incomede forma descendente y limitamos la salida a los primeros 5 registros.Con eso en mente, aquí está la solución:
SELECT first_name, monthly_income FROM `users` ORDER BY monthly_income DESC LIMIT 5
Aquí ya estás usando GROUP BY, ORDER BY, LIMIT y HAVING.
Nivel 5 — Nivel Ingeniero
-
Clasificar usuarios como "Menor", "Adulto" o "Adulto mayor".
Los dioses de las matemáticas deciden
Ahora es momento de explorar una nueva condición llamada la expresión
CASE.La expresión
CASEevalúa condiciones y devuelve un valor cuando se cumple la primera condición (similar a una estructura if-then-else). Una vez que una condición es verdadera, deja de evaluarse y retorna el resultado. Si ninguna condición se cumple, devuelve el valor definido en la cláusulaELSE.Si no existe una parte
ELSEy ninguna condición se cumple, el resultado seráNULL.Con esto en mente, continuemos:
SELECT first_name,
CASE
WHEN TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) < 18 THEN 'Minor'
WHEN TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) >= 18 AND TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) < 65 THEN 'Adult'
ELSE 'Senior'
END AS age_group
FROM usersMás información sobre la expresión
CASEaquí. -
Mostrar cuántos usuarios hay en cada una de las clasificaciones anteriores.
La verdad duele
Vamos a agrupar varios conceptos para resolver este ejercicio.
Primero, necesitamos calcular el número total de usuarios que caen dentro de un rango de edad específico:
'Minor','Adult'o'Senior'.Si un usuario coincide con una categoría determinada, sumamos
1a ese grupo usando la funciónSUM(), y luego mostramos los totales finales para cada categoría.SELECT
SUM(TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) < 18) AS 'Minor',
SUM(TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) >= 18 AND TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) < 65) AS 'Adult',
SUM(TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) >= 65) AS 'Senior'
FROM users -
Ranking de ingresos por ciudad.
Verifica mi genialidad
En este caso debemos hacer un
SUMdelmonthly_incomede la tablausersy agrupar el resultado usandoGROUP BY city.
Luego ordenamos conORDER BY incomeen orden descendente para crear el ranking.Este es el resultado:
SELECT city, SUM(monthly_income) AS income FROM users GROUP BY city ORDER BY income DESC -
Profesión con mayor ingreso promedio.
Modo esperanza ACTIVADO
Manos a la obra.
Primero debemos calcular el
AVGdelmonthly_incomede todos los usuarios y agrupar el resultado porprofession.
Luego ordenamos conORDER BY incomeen orden descendente.
Finalmente, limitamos el resultado a1para obtener el ingreso promedio más alto:SELECT profession,
ROUND(AVG(monthly_income),0) AS income
FROM users
GROUP BY profession
ORDER BY income DESC
LIMIT 1 -
Mostrar usuarios cuyo ingreso esté por encima del promedio general.
¿Respuesta final?
Y llegamos al último ejercicio. Me imagino que ya puedes estar cansado, pero no hay problema, vamos a terminarlo.
Primero necesitamos obtener la información necesaria. En este caso, requerimos
first_nameymonthly_incomede los usuariosWHEREsu ingreso sea mayor que elAVGdelmonthly_income.Con eso, terminamos con:
SELECT first_name, monthly_income AS income
FROM users
WHERE income > (SELECT AVG(monthly_income) FROM users)