Volver a la lista de artículos Artículos
Lectura de 18 minutos

20 problemas de práctica de SQL para usuarios principiantes e intermedios

¿Quieres convertirte en un experto en SQL? Intenta resolver estos 20 problemas de práctica de SQL.

Tanto si acabas de empezar tu andadura en SQL como si te estás preparando para los exámenes, necesitas afinar tus habilidades SQL si quieres convertirte en un experto. Y ya sabes lo que se dice: ¡la práctica hace al maestro!

Como la mayoría de las habilidades, SQL se aprende mejor a través de la experiencia; practicar SQL te permite aplicar tus conocimientos a escenarios del mundo real. Mediante la práctica repetida, adquirirás la confianza necesaria para sumergirte en tareas SQL complejas y destacar tanto en el ámbito académico como en el profesional.

En este artículo, he seleccionado 20 problemas de práctica de SQL de cursos de nivel principiante e intermedio. LearnSQL.es intermedio. Estos ejercicios abarcan desde los conceptos fundamentales hasta los más avanzados, lo que te proporcionará una progresión gradual para convertirte en un usuario competente de SQL. Cada ejercicio incluye explicaciones claras y una solución.

Muchos ejercicios de este artículo están inspirados en nuestro popular Ejercicio de SQL curso. Sus 9 cursos y más de 1.100 ejercicios de codificación le supondrán un auténtico reto. Si quieres más "ejercicios" de SQL después de terminar este artículo, te recomiendo que te dirijas allí.

¿Estás preparado? Empecemos. Intenta resolver cada problema antes de leer la solución.

20 Ejercicio de SQL Problemas con Soluciones

Antes de empezar, puede que quieras descargar o marcar nuestra SQL para principiantes Cheat Sheet gratuita. Resume los conceptos básicos de SQL y probablemente te será útil.

Para los siguientes problemas de práctica, utilizaré un escenario que todos conocemos: una tienda. Aquí tienes el diagrama de la base de datos:

20 Ejercicios de Problemas SQL para Usuarios Principiantes e Intermedios

Como puedes ver, la store base de datos tiene 6 tablas:

La tabla de clientes contiene información sobre los clientes. Tiene las siguientes columnas:

  • customer_id: ID interno único del cliente.
  • contact_name: Nombre completo del cliente.
  • company_name: El nombre de la empresa del cliente.
  • contact_email: La dirección de correo electrónico del cliente.
  • address: La dirección postal del cliente.
  • city: Ciudad de residencia del cliente.
  • country: País de residencia del cliente.

La tabla product contiene una lista de los productos disponibles en la tienda. Sus columnas son:

  • product_id: El ID del producto.
  • product_name: El nombre del producto.
  • category_id: El ID de la categoría del producto. Esto se conecta con category
  • quantity_per_unit: La cantidad de artículos del producto en una unidad.
  • unit_price: El precio del producto.
  • units_in_stock: El número de unidades disponibles del producto.
  • discontinued: Si el producto está disponible en la tienda (valor FALSE) o ha sido descatalogado (TRUE).

La tabla category tabla contiene información sobre las categorías de los productos:

  • category_id: El ID de la categoría.
  • name: El nombre de la categoría.
  • description: Una descripción de la categoría.
  • parent_category_id: Si esta categoría es una subcategoría, apunta a la categoría padre. En caso contrario, esta columna será NULL.

La tabla purchase contiene información sobre cada pedido:

  • purchase_id: El ID de esa compra.
  • customer_id: El ID del cliente que realizó la compra.
  • employee_id: El ID del empleado que atendió el pedido.
  • total_price: El precio total del pedido.
  • purchase_date: La fecha y hora de recepción del pedido.
  • shipped_date: La fecha y hora de envío del pedido.
  • ship_address: La dirección a la que se envió el pedido.
  • ship_city: La ciudad a la que se envió el pedido.
  • ship_country: El país al que se envió el pedido.

La tabla purchase_item relaciona las compras con los productos. Tiene las siguientes columnas obligatorias:

  • purchase_id: El ID de la compra.
  • product_id: El ID del producto comprado.
  • unit_price: El precio de una unidad de ese producto.
  • quantity: El número de unidades compradas de ese producto.

La tabla employee almacena información sobre los empleados de la tienda. Tiene las siguientes columnas:

  • employee_id: El ID del empleado.
  • last_name: El apellido del empleado.
  • first_name: El nombre del empleado.
  • birth_date: Fecha de nacimiento del empleado.
  • address: Dirección postal del empleado.
  • city: Ciudad del empleado.
  • country: País del empleado.
  • reports_to: El ID del superior directo de ese empleado. Es NULO si el empleado no depende de nadie.

Ejercicio 1: Seleccionar todas las columnas

Ejercicio

Muestre todos los datos de la product tabla.

Solución

SELECT *
FROM product;

Explicación

En esta consulta, la cláusula SELECT se utiliza para especificar las columnas que queremos recuperar de la tabla product. En este caso, el asterisco (*) es la abreviatura de "todas las columnas". La cláusula FROM especifica la tabla de la que se van a recuperar los datos. En esta consulta, es la tabla product tabla.

En resumen, la consulta pide a la base de datos que devuelva todas las columnas de cada fila de la tabla de productos.

Ejercicio 2: Seleccionar Varias Columnas

Ejercicio

Muestre los nombres y direcciones de correo electrónico de los clientes. Encontrará el nombre en la columna contact_name y el email en la columna contact_email. Renombre las columnas a name y email.

Solución

SELECT
  contact_name AS name,
  contact_email AS email
FROM customer;

Explicación

En esta consulta, la cláusula SELECT se utiliza para especificar las columnas que queremos recuperar de la tabla customer. Observe que las columnas están separadas por comas.

A continuación, utilizamos la palabra clave AS para renombrar la columna contact_name a nombre y contact_email a email. Estos nuevos nombres se denominan "alias".

Como en el caso anterior, la cláusula FROM se utiliza para indicar la tabla de la que se van a recuperar los datos; en este caso, cliente.

En conjunto, la consulta pide a la base de datos que recupere las columnas contact_name y contact_email de la tabla customer de la tabla. También le pide que muestre estas columnas como name y email, respectivamente. El conjunto de resultados estará formado por estas dos columnas alias para cada fila de la tabla customer tabla.

Ejercicio 3: Seleccionar Valores Distintos de una Tabla

Ejercicio

Muestre los ID de todos los clientes que hayan realizado al menos una compra. No se deben mostrar IDs de clientes duplicados.

Solución

SELECT DISTINCT customer_id
FROM purchase;

Explicación

Como queremos recuperar los clientes que han realizado una compra, seleccionamos sus IDs de la tabla que almacena los datos de compra, purchase. La cláusula SELECT combinada con DISTINCT elimina cualquier valor duplicado de customer_id del conjunto de resultados.

Ejercicio 4: Seleccionar Columnas Utilizando WHERE

Ejercicio

Mostrar todos los datos de un cliente con ID 4.

Solución

SELECT *
FROM customer
WHERE customer_id = 4;

Explicación

Esta consulta recupera todas las columnas (* representa todas las columnas) de la tabla customer pero sólo si el valor de la columna customer_id es igual a 4.

La cláusula WHERE filtra las filas para incluir sólo aquellas que cumplan la condición establecida - en este caso, que el valor de la columna customer_id sea igual a 4. El operador = se utiliza para la comparación de igualdades. El conjunto de resultados incluirá todas las columnas de las filas que cumplan esta condición.

Ejercicio 5: Seleccionar Columnas Utilizando WHERE con Texto

Ejercicio

Mostrar los nombres de todos los clientes que viven en Dallas.

Solución

SELECT contact_name
FROM customer
WHERE city = 'Dallas';

Explicación

Esta consulta recupera todas las columnas (*) de la tabla customer tabla. La cláusula WHERE filtra las filas para incluir sólo aquellas en las que el valor de la columna city es igual a "Dallas". Dallas' es un valor de cadena, por lo que va entre comillas simples.

Ejercicio 6: Seleccionar Columnas Usando WHERE y LIKE

Ejercicio

Mostrar todos los datos de los productos cuyos nombres empiecen por 'Carne'.

Solución

SELECT *
FROM product
WHERE product_name LIKE 'Beef%';

Explicación

La condición WHERE filtra las filas para incluir sólo aquellas en las que el valor de la columna product_name empieza por 'Beef'. El operador LIKE se utiliza para la coincidencia de patrones: 'Beef%' es un patrón en el que 'Beef' es el inicio del patrón y '%' es un comodín que coincide con cualquier secuencia de caracteres que siga a 'Beef'.

Tenga en cuenta que el operador LIKE distingue entre mayúsculas y minúsculas; los valores que empiecen por "beef" o "BEEF" no se incluirán en los resultados.

Ejercicio 7: Selección de columnas mediante WHERE y <>

Ejercicio

Mostrar los nombres de los productos y los ID de categoría relacionados para las categorías con cualquier ID distinto de 1 (Alimentos).

Solución

SELECT 
  product_name, 
  category_id
FROM product
WHERE category_id <> 1;

Explicación

Esta consulta recupera columnas específicas (product_name y category_id) de la tabla product cuando el valor de la columna category_id es distinto de 1. El operador <> es lo contrario del operador =; devuelve sólo los valores que no cumplen la condición.

Ejercicio 8: Seleccionar Columnas Usando WHERE y un Operador Lógico

Ejercicio

Mostrar los nombres de todos los clientes cuyo nombre de empresa sea Oloo o Fliptune.

Solución

SELECT
  contact_name
FROM customer
WHERE company_name = 'Oloo'
  OR company_name = 'Fliptune';

Explicación

Esta consulta recupera los nombres de los clientes de la tabla customer cuando el valor de la columna company_name es igual a "Oloo" o "Fliptune". El operador OR se utiliza para combinar estas condiciones, indicando que una de ellas debe ser verdadera para que una fila se incluya en el conjunto de resultados.

Ejercicio 9: Selección de columnas mediante WHERE, OR y AND

Ejercicio

Mostrar los datos de todos los productos de la categoría con el ID 1 (Alimentos) o 5 (Frutas y verduras) y con un precio unitario superior a 3,5.

Solución

SELECT *
FROM product
WHERE (category_id = 1 OR category_id = 5)
  AND unit_price > 3.5;

Explicación

Esta consulta recupera todas las columnas de la tabla product donde el valor de la columna category_id es igual a 1 ó 5, y el valor de la columna unit_price es superior a 3,5. Los operadores lógicos OR y AND se utilizan para combinar estas condiciones. Observe que las condiciones de OR están rodeadas de paréntesis para indicarle a SQL que ejecute este bloque primero.

Ejercicio 10: Seleccionar Columnas Usando WHERE y NOT

Ejercicio

Mostrar el nombre de todos los productos excepto los no descatalogados pertenecientes a la categoría ID 3.

Solución

SELECT product_name
FROM product
WHERE NOT (discontinued IS TRUE AND category_id = 3);

Explicación

Esta consulta recupera todas las columnas de la tabla productexcepto aquellas en las que el valor de la columna category_id es igual a 3 y el valor lógico de la columna discontinued es TRUE. La palabra clave NOT niega la condición rodeada de paréntesis, lo que significa que selecciona las filas en las que discontinued y category_id son cualquier cosa distinta de TRUE y 3.

Ejercicio 11: Ordenar Resultados de Consulta con ORDER BY

Ejercicio

Mostrar todos los datos de las compras ordenadas por fecha de envío. Las compras con fechas de envío más recientes deben mostrarse primero.

Solución

SELECT 
  purchase_id, 
  total_price, 
  shipped_date
FROM purchase
ORDER BY shipped_date DESC;

Explicación

Esta consulta recupera las columnas purchase_id, total_price y purchase_date de la tabla purchase y ordena el conjunto de resultados en función de la columna shipped_date en orden descendente. La cláusula ORDER BY ordena el conjunto de resultados en función de los valores de la columna shipped_date. La palabra clave DESC significa "descendente", lo que significa que el conjunto de resultados se ordenará en orden descendente (de las fechas más recientes a las más antiguas).

Ejercicio 12: Seleccionar y Filtrar Columnas y Ordenar Resultados

Ejercicio

Mostrar todos los datos de las compras con un precio total mayor o igual a 10. Las compras con las fechas de envío más recientes deben mostrarse primero.

Solución

SELECT *
FROM purchase
WHERE total_price >= 10
ORDER BY shipped_date DESC;

Explicación

Esta consulta recupera todas las columnas de la tabla purchase donde el valor de la columna total_price es mayor o igual que 10. También ordena el conjunto de resultados en función de la fecha de envío. También ordena el conjunto de resultados basándose en la columna shipped_date en orden descendente (DESC). La condición WHERE filtra las filas para incluir sólo aquellas en las que el valor de la columna total_price es mayor o igual que 10.

Ejercicio 13: Columnas de Grupo y COUNT()

Ejercicio

Mostrar todos los IDs de categoría y el número de productos en esa categoría.

Solución

SELECT category_id, COUNT(*)
FROM product
GROUP BY category_id;

Explicación

Esta consulta recupera el número de productos de cada categoría de la tabla product tabla. La cláusula SELECT especifica que queremos recuperar la columna category_id y el recuento de apariciones de cada category_id distinto (la función agregada COUNT(*)).

Por último, la cláusula GROUP BY agrupa los resultados en función de los valores de la columna category_id. Garantiza que el recuento se calcule para cada category_id único.

Ejercicio 14: Agrupar columnas y hallar la media

Ejercicio

Para todos los clientes, muestre el ID del cliente y el precio promedio de todas las compras para ese cliente.

Solución

SELECT 
  customer_id, 
  AVG(total_price)
FROM purchase
GROUP BY customer_id;

Explicación

Esta consulta es similar a la del ejercicio anterior - pero esta vez, utilizamos la función de agregado AVG() para mostrar el promedio de las compras de cada cliente. La cláusula SELECT devuelve la columna customer_id y la media de total_price para cada customer_id distinto de la tabla. purchase tabla.

Ejercicio 15: GROUP BY Varias Columnas

Ejercicio

Para cada par cliente-empleado, encuentre el precio total de las compras realizadas por este cliente y gestionadas por este empleado. Muestre tres columnas: customer_id, employee_id, y el precio_total de las compras. Nombre la tercera columna total_purchases_price.

Solución

SELECT
  customer_id,
  employee_id,
  SUM(total_price) AS total_purchases_price
FROM purchase
GROUP BY
  customer_id,
  employee_id;

Explicación

Esta consulta recupera los precios totales de las compras para cada par cliente-empleado. La cláusula SELECT incluye aquí la columna customer_id, la columna employee_id y la suma de las total_price para cada customer_id en la purchase tabla. La cláusula GROUP BY agrupa los resultados basándose en los valores de las columnas customer_id y employee_id.

Ejercicio 16: GROUP BY y HAVING

Ejercicio

Encuentre el menor importe de compra para cada par cliente-empleado. Muestre sólo los pares para los que haya al menos dos compras. Los nombres de las columnas deben ser customer_id, employee_id, y minimum_price.

Solución

SELECT
  customer_id,
  employee_id,
  MIN(total_price) AS minimum_price
FROM purchase
GROUP BY customer_id,
  employee_id
HAVING COUNT(total_price) >= 2;

Explicación

Esta consulta recupera los valores distintos de las columnas customer_id y employee_id junto con el precio de compra mínimo que se encuentra en la columna total_price. El precio mínimo de compra se denomina minimum_price. La cláusula GROUP BY agrupa los resultados en función de los valores de las columnas customer_id y employee_id, y la cláusula HAVING filtra los resultados para incluir sólo aquellos grupos en los que el recuento de ocurrencias es mayor o igual a 2.

¿Te han gustado estos ejercicios de GROUP BY? Ignacio L. Bisso tiene más para ti en su excelente artículo Ejercicio de SQL: 10 Ejercicios GROUP BY con Soluciones.

Ejercicio 17: Seleccionar columnas de 2 tablas con INNER JOIN

Ejercicio

Mostrar los apellidos y nombres de los empleados que se encargan de cada compra y la shipped_date de esa compra.

Solución

SELECT
  last_name,
  first_name,
  shipped_date
FROM employee
JOIN purchase
  ON employee.employee_id = purchase.employee_id;

Explicación

Esta consulta realiza una operación INNER JOIN entre las tablas employee y purchase y selecciona columnas específicas (last_name, first_name, y shipped_date) de las tablas unidas. Combina filas de la tabla employee con filas coincidentes de la tabla purchase basándose en la columna común employee_id. Si no hay ninguna coincidencia en la tabla purchase la fila no se incluirá en el conjunto de resultados.

Ejercicio 18: Seleccionar Columnas de 4 Tablas con LEFT JOIN

Ejercicio

Muestre los nombres y correos electrónicos de todos los clientes y enumere los nombres de los productos que compraron y el precio del producto en el momento de la compra. Incluya a los clientes que no han realizado ninguna compra. No renombre las columnas.

Solución

SELECT
  contact_name,
  contact_email,
  product_name,
  purchase_item.unit_price
FROM customer
LEFT JOIN purchase
  ON customer.customer_id = purchase.customer_id
LEFT JOIN purchase_item
  ON purchase.purchase_id = purchase_item.purchase_id
LEFT JOIN product
  ON purchase_item.product_id = product.product_id;

Explicación

Esta consulta realiza una triple operación LEFT JOIN entre los archivos customer, purchase, purchase_itemy product y selecciona columnas específicas (contact_name, contact_email, product_name, y unit_price) del conjunto de resultados. Combina filas de la tabla customer con filas coincidentes de la tabla purchase, purchase_itemy product basándose en las columnas comunes customer_id, purchase_id, y product_id.

Si no hay ninguna coincidencia en la tabla purchase se incluirán valores de NULL en el conjunto de resultados para las columnas de la tabla purchase_item tabla.

Ejercicio 19: Combinación de INNER JOIN, GROUP BY y HAVING

Ejercicio

Para cada categoría, encuentre el número de productos descatalogados. Muestre sólo las categorías con al menos tres productos discontinuados. Ordene las filas por el número de productos descatalogados en orden descendente. Mostrar dos columnas: nombre (el nombre de la categoría) y discontinued_products_number.

Solución

SELECT
  category.name,
  COUNT(product_id) AS discontinued_products_number
FROM product
JOIN category
  ON product.category_id = category.category_id
WHERE discontinued IS TRUE
GROUP BY category.name
HAVING COUNT(product_id) >= 3
ORDER BY COUNT(product_id) DESC;

Explicación

Esta consulta realiza una operación INNER JOIN entre los campos product y category tablas. Muestra category name y el recuento de apariciones de cada product_id distinto en el conjunto de resultados. Combina las filas de la tabla product con filas coincidentes de la tabla category a partir de la columna común category_id.

Las filas se agrupan por nombres de categoría; la función de agregado COUNT() se utiliza en la columna category_id para devolver el número de productos de esa categoría. La cláusula HAVING filtra las categorías con al menos productos descatalogados. Las filas se muestran en orden descendente de ID de producto (ORDER BY COUNT(product_id) DESC).

Ejercicio 20: Otra consulta INNER JOIN, GROUP BY y HAVING

Ejercicio

Para cada cliente, muestre el número de compras que ha realizado. Incluya sólo las compras con un ship_city que no sea NULL y muestre sólo los clientes cuyo coste total de todas las compras sea superior a 14. Los nombres de las columnas deben ser contact_name y purchase_quantity. Ordene las filas por contact_name.

Solución

SELECT
  contact_name,
  COUNT(*) AS purchase_quantity
FROM purchase
JOIN customer
  ON purchase.customer_id = customer.customer_id
WHERE ship_city IS NOT NULL
GROUP BY contact_name
HAVING SUM(total_price) > 14
ORDER BY contact_name;

Explicación

Esta consulta realiza una operación INNER JOIN entre las columnas purchase y customer y selecciona el contact_name y el recuento de apariciones de cada compra distinta del conjunto de resultados. Las filas se agrupan por nombres de contacto. La cláusula HAVING permite filtrar por el precio total requerido.

¿Le han resultado desafiantes estos ejercicios de JOIN? Te recomiendo que leas SQL Joins: 12 Preguntas Prácticas con Respuestas Detalladas por Tihomir Babic.

Más problemas de Ejercicio de SQL en LearnSQL.com

Si te gustaron los problemas de práctica anteriores, puedes encontrar más problemas de práctica de SQL en LearnSQL.es. Cada problema de práctica está cuidadosamente diseñado con pistas, soluciones y explicaciones. Este enfoque garantiza que los principiantes no sólo resuelvan el problema, sino que también aprendan los conceptos fundamentales de SQL. A diferencia de los ejercicios teóricos convencionales, los problemas prácticos de LearnSQL.es son prácticos y están relacionados con situaciones de la vida real. Estos problemas realistas refuerzan la comprensión teórica y aumentan significativamente su confianza.

Aquí tienes algunos cursos de LearnSQL.es que te recomiendo especialmente si buscas más práctica:

SQL Practice: University

El curso SQL Practice: University es ideal para estudiantes y principiantes en SQL. Basado en un escenario real (una universidad ficticia), este curso proporciona 156 ejercicios interactivos de SQL. Los ejercicios iniciales se centran en la construcción de consultas SELECT básicas, mientras que los posteriores le retan a elaborar consultas SQL avanzadas. Utilizará SELECT, WHERE, varios JOINs, GROUP BY, HAVING, ORDER BY, operadores de conjunto y subconsultas.

Basic SQL Practice: A Store

El curso Basic SQL Practice: A Store es una excelente opción para las personas que gestionan una tienda física o una tienda en línea y desean mejorar sus habilidades de dominio de datos. Al realizar este curso, no sólo mejorará su comprensión de los datos, sino que también aumentará potencialmente sus beneficios. Si gestiona una aplicación de marca blanca adaptada a los propietarios de tiendas (como un ERP), este curso está diseñado para usted. Cubre una amplia gama de temas, incluyendo productos, categorías, inventario, compras, gestión de empleados y más.

Basic SQL Practice: Run Track Through Queries!

El curso Basic SQL Practice: Run Track Through Queries! incluye trabajo práctico con datos auténticos. Profundiza en una base de datos repleta de información de los Juegos Olímpicos de Río, los Campeonatos del Mundo de la IAAF de 2019 en Doha y los Campeonatos del Mundo de la IAAF de 2017 en Londres. Descubre a los campeones de carreras de velocidad, maratones y largas distancias, determina los países con mejores resultados, encuentra velocidades y distancias medias, y mucho más. Tanto si te apasionan los deportes, el atletismo o los conocimientos relacionados con las pistas, este curso te ofrece una experiencia a tu medida.

Basic SQL Practice: Blog & Traffic Data

El curso Basic SQL Practice: Blog & Traffic Data está diseñado para personas que supervisan un blog con mucho tráfico. Pondrá a prueba sus conocimientos de SQL mientras analiza diversos aspectos de los datos del blog, como la popularidad de los artículos, la evaluación del rendimiento de los autores y el éxito de las promociones de productos basadas en artículos. Tanto si es propietario de un blog, administrador o estudiante de SQL, este curso se adapta a sus necesidades.

Lo mejor son los problemas prácticos con escenarios del mundo real. Jakub Romanowski resumió los principales lugares donde encontrar conjuntos de datos en su artículo ¿Dónde puedo encontrar conjuntos de datos en línea gratuitos para practicar SQL?

Ejercicio de SQL Problemas: El camino a seguir

Espero que este artículo te haya ayudado a practicar SQL. Cada reto al que te enfrentas es un paso adelante hacia el dominio de SQL. Tanto si eres un estudiante que acaba de empezar como un especialista que busca perfeccionar sus habilidades, cada problema de práctica es un bloque de construcción en su base de aprendizaje. Acepta el viaje, disfruta del proceso y recuerda que cada problema de práctica de SQL te acerca un paso más a convertirte en un experto. Sigue codificando, sigue creciendo y sigue practicando SQL para alcanzar el éxito.

Un último consejo: todos los meses publicamos un nuevo curso práctico de SQL en nuestra sección Práctica mensual de SQL. Te permitirá aprender resolviendo problemas SQL de forma continua y progresiva.

Gracias por leer este artículo; ¡nos vemos en el próximo!