Lesión 4.2 · Tiempo de lectura: ~7 minutos
La agrupación transforma filas individuales en métricas categorizadas. GROUP BY es esencial para informes donde necesitas totales por categoría, fecha o cualquier otra dimensión. En esta lección, aprenderás la sintaxis de GROUP BY, la regla fundamental y ejemplos prácticos en Sakila. Al final, podrás construir consultas analíticas con agrupación con confianza.
Agrupación de Datos con GROUP BY
En la lección anterior, aprendiste sobre funciones agregadas. Ahora damos el siguiente paso: aplicar esas funciones a diferentes categorías de datos.
GROUP BY hace esto dividiendo los datos en grupos y calculando métricas para cada grupo por separado.
Sintaxis de GROUP BY
Estructura básica:
SELECT column1, AGG_FUNCTION(column2)
FROM table
GROUP BY column1;
La Regla Fundamental
Al usar GROUP BY, cada columna en SELECT debe:
- estar en la lista de
GROUP BY; - o estar envuelta en una función agregada (
SUM,COUNT,AVG,MIN,MAX).
Esta regla previene ambigüedades: SQL necesita saber qué valor devolver cuando un grupo tiene múltiples filas.
Agrupación 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 su suma total de pagos.
Número de pagos por miembro del personal
SELECT staff_id, COUNT(*) AS payments_count
FROM payment
GROUP BY staff_id;
Resultado: para cada miembro del personal, el conteo de pagos que procesaron.
Pago promedio 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 monto promedio de pago.
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 compatibilidad entre SGBD, escribe GROUP BY DATE(payment_date) en su totalidad.
Agrupación por Múltiples Columnas
Puedes agrupar por múltiples campos a la vez para un análisis más detallado.
Total de pagos por personal y cliente
SELECT staff_id, customer_id, SUM(amount) AS total_paid
FROM payment
GROUP BY staff_id, customer_id;
Resultado: una fila por par de personal-cliente con su total de pago.
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 conteo de alquileres
SELECT customer_id, COUNT(*) AS rentals_count
FROM rental
GROUP BY customer_id
ORDER BY rentals_count DESC;
Tasa de alquiler promedio 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 incluir cada columna en SELECT si uso GROUP BY?
Porque las funciones agregadas (SUM, COUNT, AVG) ya le dicen a SQL cómo manejar todas las filas en el 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 GROUP BY.
¿Qué pasa si GROUP BY está vacío?
Eso es un error de sintaxis. GROUP BY siempre necesita al menos una columna o expresión.
Preguntas de Entrevista
¿Qué es GROUP BY y por qué lo necesitamos?
GROUP BY combina filas donde las columnas seleccionadas tienen valores idénticos en un solo grupo. Luego puedes aplicar funciones agregadas a cada grupo para obtener estadísticas resumidas.
¿Por qué no puedo seleccionar arbitrariamente una columna al usar GROUP BY?
Porque un grupo puede contener múltiples filas con diferentes valores en esa columna. SQL necesita saber qué valor devolver, de lo contrario, el resultado es ambiguo. Por lo tanto, la columna debe estar en GROUP BY o dentro de una función agregada.
¿Cuál es la diferencia entre WHERE y HAVING?
WHERE filtra filas ANTES de la agrupación, mientras que HAVING filtra grupos DESPUÉS de la agrupación. Por ejemplo, WHERE amount > 10 excluye filas antes de la agrupación, mientras que HAVING SUM(amount) > 100 excluye grupos cuya suma es menor a 100.
Conclusiones clave de esta lección:
GROUP BYdivide los datos en grupos y aplica agregados a cada uno.- Regla fundamental: todas las columnas de SELECT deben estar en GROUP BY o en una función agregada.
- Puedes agrupar por una o múltiples columnas simultáneamente.
- Puedes agrupar por expresiones, como
GROUP BY DATE(payment_date). GROUP BYpotencia informes, análisis y resúmenes basados en categorías.
En la próxima lección, exploraremos el filtrado de grupos con el operador HAVING.