🙏 Realmente necesitamos su apoyo. Necesitamos financiamiento para continuar nuestra misión: publicar nuevas lecciones y mejorar la plataforma. Si puede, por favor apoye el proyecto con una donación. Ayude al proyecto ahora →
Código SQL copiado al portapapeles

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 BY divide 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 BY potencia 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.