Agrupar datos con GROUP BY
Lección 4.2 · Tiempo de lectura: ~7 min · Tareas de práctica ↓
La agrupación convierte filas individuales en métricas por categorías. GROUP BY es imprescindible en los informes que necesitan totales por categoría, fecha o cualquier otra dimensión. En esta lección aprenderás la sintaxis de GROUP BY, su regla principal y ejemplos prácticos con Sakila. Al terminar, construirás con seguridad consultas analíticas con agrupación.
En la lección anterior conociste las funciones de agregación. Ahora damos el siguiente paso: aplicarlas a distintas categorías de datos.
GROUP BY lo hace dividiendo los datos en grupos y calculando las métricas de cada grupo por separado.
Sintaxis de GROUP BY
Estructura básica:
SELECT column1, AGG_FUNCTION(column2)
FROM table
GROUP BY column1;
La regla principal
Al usar GROUP BY, cada columna de SELECT debe:
- o bien estar en la lista de
GROUP BY; - o bien estar dentro de una función de agregación (
SUM,COUNT,AVG,MIN,MAX).
Esta regla evita la ambigüedad: SQL necesita saber qué valor devolver cuando un grupo tiene varias filas.
Agrupar por una columna
Total de pagos por cliente
SELECT customer_id, SUM(amount) AS total_paid
FROM payment
GROUP BY customer_id;
Resultado: una fila por cliente con la suma total de sus pagos.
Número de pagos por empleado
SELECT staff_id, COUNT(*) AS payments_count
FROM payment
GROUP BY staff_id;
Resultado: para cada empleado, el número de pagos que ha procesado.
Pago medio por fecha
SELECT DATE(payment_date) AS pay_date, AVG(amount) AS avg_payment
FROM payment
GROUP BY DATE(payment_date);
Resultado: para cada fecha, el importe medio de los pagos.
Variante: GROUP BY con alias
SELECT DATE(payment_date) AS pay_date, AVG(amount) AS avg_payment
FROM payment
GROUP BY pay_date;
Nota: esto funciona en MySQL/MariaDB, pero no en todos los SGBD. Para que la consulta sea compatible con otras bases de datos, escribe GROUP BY DATE(payment_date) completo.
Agrupar por varias columnas
Puedes agrupar por varios campos a la vez para un análisis más detallado.
Total de pagos por empleado y cliente
SELECT staff_id, customer_id, SUM(amount) AS total_paid
FROM payment
GROUP BY staff_id, customer_id;
Resultado: una fila por cada par empleado-cliente con su total de pagos.
Ejemplos prácticos
Informe de ingresos diarios
SELECT DATE(payment_date) AS pay_date, SUM(amount) AS total_sales
FROM payment
GROUP BY DATE(payment_date)
ORDER BY pay_date;
Clientes más activos por número de alquileres
SELECT customer_id, COUNT(*) AS rentals_count
FROM rental
GROUP BY customer_id
ORDER BY rentals_count DESC;
Tarifa media de alquiler por categoría de película
SELECT category_id, AVG(rental_rate) AS avg_rental_rate
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
GROUP BY category_id;
Preguntas frecuentes
¿Por qué no puedo poner cualquier columna en SELECT si uso GROUP BY?
Porque las funciones de agregación (SUM, COUNT, AVG) ya indican a SQL cómo tratar todas las filas del grupo. Si una columna no está agregada, debe estar en GROUP BY para que SQL sepa qué valor elegir.
¿Puedo agrupar por una expresión en lugar de una columna?
Sí, por ejemplo GROUP BY DATE(payment_date) o GROUP BY YEAR(payment_date). La expresión debe coincidir en SELECT y en GROUP BY.
¿Qué pasa si GROUP BY está vacío?
Es un error de sintaxis. GROUP BY siempre necesita al menos una columna o expresión.
Preguntas de entrevista
¿Qué es GROUP BY y para qué lo necesitamos?
GROUP BY reúne en un mismo grupo las filas cuyas columnas seleccionadas tienen valores idénticos. Después puedes aplicar funciones de agregación a cada grupo para obtener estadísticas de resumen.
¿Por qué no puedo seleccionar cualquier columna al usar GROUP BY?
Porque un grupo puede contener varias filas con valores distintos en esa columna. SQL necesita saber qué valor devolver; si no, el resultado es ambiguo. Por eso la columna debe estar en GROUP BY o dentro de una función de agregación.
¿Qué diferencia hay entre WHERE y HAVING?
WHERE filtra filas ANTES de agrupar, mientras que HAVING filtra grupos DESPUÉS de agrupar. Por ejemplo, WHERE amount > 10 excluye filas antes de agrupar, mientras que HAVING SUM(amount) > 100 excluye los grupos cuya suma es menor que 100.
Puntos clave de esta lección:
GROUP BYdivide los datos en grupos y aplica las funciones de agregación a cada uno.- Regla principal: cada columna de SELECT va en GROUP BY o dentro de una función de agregación.
- Puedes agrupar por una o por varias columnas a la vez.
- Puedes agrupar por expresiones, como
GROUP BY DATE(payment_date). GROUP BYes la base de informes, analítica y resúmenes por categoría.