Estos 20 ejercicios permiten practicar SQL de forma progresiva. Antes de mirar cada solución, intentá resolver el enunciado por tu cuenta.
Base de datos utilizada
Trabajamos con clientes, categorías, productos, ventas y ventas_detalles.
Las relaciones principales son:
productos.categoria_id → categorias.id;ventas.cliente_id → clientes.id;ventas_detalles.venta_id → ventas.id;ventas_detalles.producto_id → productos.id.
Conviene tener este mapa mental antes de resolver los ejercicios con JOIN.
Cómo leer cada ejercicio
Antes de mirar la solución, intentá responder:
- ¿qué resultado final necesito?
- ¿qué tabla tiene esa información?
- ¿necesito filtrar filas?
- ¿necesito relacionar tablas?
- ¿necesito agrupar o calcular un resumen?
Resolver SQL es, en gran parte, aprender a traducir una pregunta del negocio a esas decisiones.
1. Mostrar todos los clientes
SELECT * FROM clientes;
Explicación: Usamos SELECT * porque queremos todas las columnas de todas las filas.
2. Mostrar nombre y apellido
SELECT nombre, apellido FROM clientes;
Explicación: Seleccionar solo las columnas necesarias hace la consulta más clara.
3. Clientes de Santa Rosa
SELECT * FROM clientes WHERE ciudad = 'Santa Rosa';
Explicación: WHERE filtra las filas por ciudad. La consulta primero parte de todos los clientes y después conserva solamente los que cumplen la condición.
4. Productos con precio mayor a 100000
SELECT nombre, precio FROM productos WHERE precio > 100000;
Explicación: El operador > compara valores numéricos.
5. Productos con stock bajo
SELECT nombre, stock FROM productos WHERE stock < 10;
Explicación: Este tipo de consulta puede utilizarse para alertas de reposición.
6. Ordenar productos por precio
SELECT nombre, precio FROM productos ORDER BY precio DESC;
Explicación: DESC ordena del valor más alto al más bajo.
7. Tres productos más caros
SELECT nombre, precio FROM productos ORDER BY precio DESC LIMIT 3;
Explicación: Primero ordenamos y luego LIMIT conserva solo las tres primeras filas.
8. Contar productos
SELECT COUNT(*) AS total_productos FROM productos;
Explicación: COUNT(*) devuelve cuántas filas tiene la tabla.
9. Precio promedio
SELECT AVG(precio) AS precio_promedio FROM productos;
Explicación: AVG calcula la media aritmética de la columna.
10. Productos por categoría
SELECT categoria_id, COUNT(*) AS cantidad FROM productos GROUP BY categoria_id;
Explicación: GROUP BY crea un grupo por categoría y COUNT cuenta sus productos. El resultado tendrá una fila por cada categoria_id, no una fila por cada producto.
11. Productos con categoría
SELECT p.nombre AS producto, c.nombre AS categoria FROM productos AS p INNER JOIN categorias AS c ON p.categoria_id = c.id;
Explicación: JOIN combina cada producto con la categoría relacionada. La condición p.categoria_id = c.id indica exactamente qué filas deben emparejarse.
12. Ventas con nombre del cliente
SELECT v.id, v.fecha, c.nombre, c.apellido, v.total FROM ventas AS v INNER JOIN clientes AS c ON v.cliente_id = c.id;
Explicación: Reemplazamos el identificador del cliente por información legible.
13. Total comprado por cliente
SELECT c.id, c.nombre, c.apellido, SUM(v.total) AS total_comprado FROM clientes AS c INNER JOIN ventas AS v ON v.cliente_id = c.id GROUP BY c.id, c.nombre, c.apellido;
Explicación: SUM acumula las ventas dentro de cada grupo de cliente. Primero JOIN conecta ventas con clientes; después GROUP BY reúne las ventas de la misma persona y finalmente SUM calcula el total.
14. Clientes que gastaron más de 100000
SELECT c.nombre, c.apellido, SUM(v.total) AS total_comprado FROM clientes AS c INNER JOIN ventas AS v ON v.cliente_id = c.id GROUP BY c.id, c.nombre, c.apellido HAVING SUM(v.total) > 100000;
Explicación: HAVING filtra después de calcular la suma por cliente. No usamos WHERE para SUM(v.total) porque ese valor todavía no existe antes de formar los grupos.
15. Clientes sin ventas
SELECT c.id, c.nombre, c.apellido FROM clientes AS c LEFT JOIN ventas AS v ON v.cliente_id = c.id WHERE v.id IS NULL;
Explicación: LEFT JOIN conserva clientes sin coincidencia; NULL identifica los que nunca compraron. Es un patrón muy usado para buscar “registros sin relación”.
16. Productos más vendidos
SELECT p.nombre, SUM(vd.cantidad) AS unidades_vendidas FROM productos AS p INNER JOIN ventas_detalles AS vd ON vd.producto_id = p.id GROUP BY p.id, p.nombre ORDER BY unidades_vendidas DESC;
Explicación: Sumamos cantidades por producto y ordenamos el ranking.
17. Producto con mayor facturación
SELECT p.nombre, SUM(vd.subtotal) AS facturacion FROM productos AS p INNER JOIN ventas_detalles AS vd ON vd.producto_id = p.id GROUP BY p.id, p.nombre ORDER BY facturacion DESC LIMIT 1;
Explicación: El primer registro del ranking es el producto con mayor facturación.
18. Ventas por encima del promedio
SELECT id, cliente_id, total FROM ventas WHERE total > (SELECT AVG(total) FROM ventas);
Explicación: La subconsulta calcula el promedio y la consulta externa compara cada venta. Conviene ejecutar primero la subconsulta sola para comprobar qué valor produce.
19. Productos nunca vendidos
SELECT p.id, p.nombre FROM productos AS p LEFT JOIN ventas_detalles AS vd ON vd.producto_id = p.id WHERE vd.id IS NULL;
Explicación: Buscamos productos que no tienen ninguna fila relacionada en detalles.
20. Cliente que más gastó
SELECT c.id, c.nombre, c.apellido, SUM(v.total) AS total_gastado FROM clientes AS c INNER JOIN ventas AS v ON v.cliente_id = c.id GROUP BY c.id, c.nombre, c.apellido ORDER BY total_gastado DESC LIMIT 1;
Explicación: Agrupamos, sumamos, ordenamos y conservamos el primer cliente.
Qué conceptos aparecen en estos 20 ejercicios
- selección de columnas;
- filtros con WHERE;
- orden y límites;
- funciones de agregación;
- GROUP BY y HAVING;
- INNER JOIN y LEFT JOIN;
- subconsultas;
- rankings simples.
Cómo practicar
- identificá qué tabla contiene el dato;
- decidí si necesitás WHERE;
- si hay varias tablas, buscá la relación;
- si necesitás resumir, pensá en GROUP BY;
- recién después escribí SQL.
¿Qué sigue?
20 ejercicios intermedios y avanzados.
¿Te sirvió esta guía? ☕
Si este contenido te ayudó y querés apoyar a Club Programador para seguir publicando ejercicios, proyectos y guías gratuitas, podés colaborar mediante:
Ruta SQL / MySQL
Ver todos los contenidos de SQL / MySQL
20 ejercicios intermedios y avanzados →
Descubre más desde Club Programador
Suscríbete y recibe las últimas entradas en tu correo electrónico.
2 opiniones en “20 ejercicios de SQL resueltos: SELECT, WHERE, JOIN, GROUP BY y subconsultas”