Concepto clave
Imagina que tienes una lista de ventas de tu tienda. Quieres saber cuánto vendió cada vendedor, o cuántas unidades se vendieron por producto. GROUP BY es la herramienta que te permite agrupar filas que comparten un valor común y luego aplicar funciones de resumen (como SUM, COUNT, AVG) a cada grupo.
En la vida real, piensa en un montón de recibos de compras. Si quieres saber el total gastado por cada cliente, agrupas los recibos por cliente y sumas los montos. Eso es exactamente lo que hace GROUP BY en SQL.
La sintaxis básica es: SELECT columna_agrupada, función_resumen(columna) FROM tabla GROUP BY columna_agrupada. La columna que aparece en SELECT debe estar en GROUP BY o ser una función de resumen.
Cómo funciona en la práctica
Supón que tienes una tabla llamada ventas con las columnas: id, vendedor, producto, cantidad, precio. Quieres saber el total vendido por cada vendedor.
Primero, piensa en los grupos: cada vendedor único es un grupo. Luego, para cada grupo, sumas el precio * cantidad (ingreso). La consulta sería:
SELECT vendedor, SUM(cantidad * precio) AS total_ingresos
FROM ventas
GROUP BY vendedor;Esto devuelve una fila por cada vendedor con su total. Si además quieres filtrar solo vendedores con ventas mayores a 1000, usas HAVING (no WHERE, porque WHERE filtra antes de agrupar):
SELECT vendedor, SUM(cantidad * precio) AS total_ingresos
FROM ventas
GROUP BY vendedor
HAVING total_ingresos > 1000;Código en acción
Vamos a crear una tabla de ejemplo y ejecutar consultas. Primero, crea la tabla e inserta datos:
CREATE TABLE ventas (
id INT PRIMARY KEY,
vendedor VARCHAR(50),
producto VARCHAR(50),
cantidad INT,
precio DECIMAL(10,2)
);
INSERT INTO ventas VALUES
(1, 'Ana', 'Laptop', 2, 15000),
(2, 'Luis', 'Mouse', 5, 200),
(3, 'Ana', 'Teclado', 3, 800),
(4, 'Luis', 'Laptop', 1, 15000),
(5, 'Sofia', 'Monitor', 2, 4000);Ahora, consulta el total de ingresos por vendedor:
SELECT vendedor, SUM(cantidad * precio) AS total_ingresos
FROM ventas
GROUP BY vendedor;Resultado esperado:
vendedor | total_ingresos
Ana | 32400
Luis | 16000
Sofia | 8000Si quieres contar cuántas ventas hizo cada vendedor:
SELECT vendedor, COUNT(*) AS num_ventas
FROM ventas
GROUP BY vendedor;Resultado:
vendedor | num_ventas
Ana | 2
Luis | 2
Sofia | 1Errores comunes
- Olvidar incluir todas las columnas no agregadas en GROUP BY: Si SELECT tiene una columna que no está en GROUP BY y no es función de resumen, SQL arrojará error. Solución: asegúrate de que cada columna en SELECT esté en GROUP BY o sea agregada.
- Usar WHERE en lugar de HAVING para filtrar grupos: WHERE filtra filas antes de agrupar; HAVING filtra después. Si quieres filtrar por resultado de agregación (ej. SUM > 100), usa HAVING.
- Confundir COUNT(*) con COUNT(columna): COUNT(*) cuenta todas las filas del grupo, incluyendo NULLs. COUNT(columna) cuenta solo las filas donde columna no es NULL. Úsalos según necesites.
- No usar alias en funciones de resumen: El resultado de SUM(cantidad) se muestra como 'SUM(cantidad)'. Usa alias (AS) para darle un nombre claro.
- Agrupar por columnas con muchos valores únicos: Si agrupas por una columna como 'id', cada grupo tendrá una sola fila, y GROUP BY no tiene sentido. Asegúrate de agrupar por columnas que tengan valores repetidos.
Checklist de dominio
- Puedo escribir una consulta SELECT con GROUP BY para agrupar datos por una columna.
- Puedo usar funciones de resumen (SUM, COUNT, AVG, MIN, MAX) dentro de GROUP BY.
- Puedo usar HAVING para filtrar grupos después de agrupar.
- Puedo explicar la diferencia entre WHERE y HAVING.
- Puedo evitar el error de columnas no agregadas fuera de GROUP BY.
- Puedo agrupar por múltiples columnas (ej. GROUP BY vendedor, producto).
- Puedo crear una consulta que devuelva el total de ventas por vendedor y producto.
Ejercicio: Reporte de ventas por categoría
Tu tarea es generar un reporte de ventas agrupado por categoría de producto. Usa la tabla productos y ventas que se definen a continuación.
Paso 1: Crear las tablas
CREATE TABLE productos (
id INT PRIMARY KEY,
nombre VARCHAR(50),
categoria VARCHAR(50),
precio DECIMAL(10,2)
);
CREATE TABLE ventas (
id INT PRIMARY KEY,
producto_id INT,
cantidad INT,
fecha DATE,
FOREIGN KEY (producto_id) REFERENCES productos(id)
);
INSERT INTO productos VALUES
(1, 'Laptop', 'Electrónica', 15000),
(2, 'Mouse', 'Electrónica', 200),
(3, 'Teclado', 'Electrónica', 800),
(4, 'Camisa', 'Ropa', 500),
(5, 'Pantalón', 'Ropa', 700);
INSERT INTO ventas VALUES
(1, 1, 2, '2024-01-10'),
(2, 2, 5, '2024-01-11'),
(3, 3, 3, '2024-01-12'),
(4, 4, 4, '2024-01-13'),
(5, 5, 1, '2024-01-14'),
(6, 1, 1, '2024-01-15');Paso 2: Escribir la consulta
Escribe una consulta SQL que devuelva: categoria, total_ingresos (suma de cantidad * precio) y num_ventas (conteo de ventas) para cada categoría. Ordena el resultado por total_ingresos descendente.
Paso 3: Verificar el resultado
El resultado esperado es:
categoria | total_ingresos | num_ventas
Electrónica | 32900 | 4
Ropa | 2700 | 2Mini-rúbrica de evaluación:
- La consulta usa GROUP BY correctamente (1 punto)
- Usa SUM y COUNT con alias (1 punto)
- Incluye JOIN entre ventas y productos (1 punto)
- Ordena por total_ingresos DESC (1 punto)
- El resultado coincide con el esperado (1 punto)
Entregable: La consulta SQL completa como texto.
Pistas- Recuerda que necesitas unir las tablas ventas y productos usando producto_id = productos.id
- Para calcular el ingreso, multiplica cantidad por el precio del producto (ventas.cantidad * productos.precio)
- Usa ORDER BY total_ingresos DESC al final