📘 Lección 8: Agrupación y filtros de grupos — GROUP BY y HAVING

🔹 Introducción

En la lección anterior aprendiste a usar las funciones de agregación (COUNT, SUM, AVG, MIN, MAX) para obtener resúmenes de información.

Pero muchas veces no queremos un único valor para toda la tabla, sino resúmenes por categoría.
Ejemplos:

  • ¿Cuántos alumnos hay en cada ciudad?
  • ¿Cuál es la edad promedio en cada ciudad?
  • ¿Qué ciudades tienen más de un alumno?

👉 Para eso existen dos herramientas en SQL:

  • GROUP BY → agrupa los registros que comparten un mismo valor.
  • HAVING → filtra los grupos resultantes después de agrupar.

🔹 Nuestra tabla de ejemplo

Seguimos trabajando con la tabla alumnos:

idnombreedadciudad
1Ana20Buenos Aires
2Juan17Ciudad de México
3Laura22Madrid
4Pedro18Madrid

🔹 Ejemplo 1: contar alumnos por ciudad

Queremos saber cuántos alumnos hay en cada ciudad:

SELECT ciudad, COUNT(*) AS cantidad_alumnos
FROM alumnos
GROUP BY ciudad;

👉 Resultado esperado:

ciudadcantidad_alumnos
Buenos Aires1
Ciudad de México1
Madrid2

🔹 Ejemplo 2: promedio de edad por ciudad

SELECT ciudad, AVG(edad) AS promedio_edad
FROM alumnos
GROUP BY ciudad;

👉 Resultado esperado:

ciudadpromedio_edad
Buenos Aires20
Ciudad de México17
Madrid20

(En Madrid, el promedio es (22 + 18) / 2 = 20)

🔹 Ejemplo 3: agrupar por varias columnas

Podemos agrupar por más de un campo.
Por ejemplo, cuántos alumnos hay por ciudad y por edad:

SELECT ciudad, edad, COUNT(*) AS cantidad
FROM alumnos
GROUP BY ciudad, edad;

Esto devuelve el conteo para cada combinación de ciudad + edad.

🔹 Ejemplo 4: diferencia entre WHERE y HAVING

  • WHERE filtra filas antes de agrupar.
  • HAVING filtra después de agrupar.

Usando WHERE

Queremos contar los alumnos por ciudad, pero solo los que tienen 18 años o más:

SELECT ciudad, COUNT(*) AS mayores
FROM alumnos
WHERE edad >= 18
GROUP BY ciudad;

👉 Resultado esperado:

ciudadmayores
Buenos Aires1
Madrid2

Usando HAVING

Queremos mostrar solo las ciudades que tengan más de 1 alumno:

SELECT ciudad, COUNT(*) AS cantidad
FROM alumnos
GROUP BY ciudad
HAVING COUNT(*) > 1;

👉 Resultado esperado:

ciudadcantidad
Madrid2

🔹 Ejemplo 5: condiciones combinadas

Queremos mostrar las ciudades que tengan más de 1 alumno y cuyo promedio de edad sea mayor o igual a 20:

SELECT ciudad, COUNT(*) AS cantidad, AVG(edad) AS promedio
FROM alumnos
GROUP BY ciudad
HAVING COUNT(*) > 1 AND AVG(edad) >= 20;

👉 Resultado esperado:

ciudadcantidadpromedio
Madrid220

🔹 Ejercicio práctico (para ti)

  1. Muestra la cantidad de alumnos por ciudad.
  2. Muestra el promedio de edad por ciudad.
  3. Muestra únicamente las ciudades que tengan más de 1 alumno.
  4. Muestra las ciudades donde la edad mínima (MIN(edad)) sea mayor o igual a 18.

🔹 Soluciones

SELECT ciudad, COUNT(*) 
FROM alumnos
GROUP BY ciudad;
SELECT ciudad, AVG(edad)
FROM alumnos
GROUP BY ciudad;
SELECT ciudad, COUNT(*)
FROM alumnos
GROUP BY ciudad
HAVING COUNT(*) > 1;
SELECT ciudad, MIN(edad)
FROM alumnos
GROUP BY ciudad
HAVING MIN(edad) >= 18;

📝 Mini Quiz

 

Resultados

#1. ¿Qué hace GROUP BY en SQL?

#2. ¿Qué comando se usa para filtrar después de agrupar?

#3. Si agrupamos a los alumnos por ciudad y mostramos solo las ciudades con más de un alumno, ¿qué se obtendrá?

Previa
Finalizar

🔹 Resumen de la lección

  • GROUP BY permite agrupar registros según una columna o varias.
  • Se suele usar junto con funciones de agregación (COUNT, AVG, SUM, MIN, MAX).
  • WHERE filtra filas antes de agrupar.
  • HAVING filtra los grupos resultantes después de agrupar.
  • Podés combinar GROUP BY con HAVING para obtener estadísticas más detalladas.

👉 En la próxima lección aprenderás a combinar tablas con JOINs (INNER, LEFT, RIGHT), lo que te permitirá trabajar con múltiples tablas al mismo tiempo.

📊 Esta lección forma parte de un programa más amplio. Ingresa al curso completo de SQL para continuar.

Scroll al inicio