Funciones agregadas y agrupación — Conceptos
Las funciones agregadas calculan un único valor a partir de múltiples filas: cuántas hay, cuánto suman, cuál es la media, el mínimo y el máximo. Combinadas con GROUP BY se convierten en la herramienta principal para analizar datos por segmentos, y con HAVING se pueden filtrar esos segmentos con precisión quirúrgica.
Resumen rápido
Las funciones agregadas calculan un único valor a partir de múltiples filas: cuántas hay, cuánto suman, cuál es la media, el mínimo y el máximo. Combinadas con GROUP BY se convierten en la herramienta principal para analizar datos por segmentos, y con HAVING se pueden filtrar esos segmentos con precisión quirúrgica.
Conceptos clave
Función que recibe un conjunto de filas y devuelve un único valor de resumen: COUNT, SUM, AVG, MIN o MAX. Su resultado depende de todas las filas procesadas, no de una sola.
Cuenta filas. COUNT(*) cuenta todas las filas, COUNT(columna) cuenta solo las no nulas, COUNT(DISTINCT columna) cuenta los valores únicos eliminando duplicados.
Suma todos los valores numéricos de una columna. No funciona con texto ni con booleanos. Ignora los valores nulos.
Calcula el promedio aritmético de una columna numérica. Los valores nulos se ignoran: no arrastran el promedio hacia cero ni cuentan como divisor.
Devuelven el valor mínimo o máximo de una columna. Funcionan con números, fechas y texto (ordenamiento alfabético). No funcionan con booleanos.
Agrupa las filas que comparten el mismo valor en una o varias columnas. Todas las columnas del SELECT que no sean funciones agregadas deben aparecer también en el GROUP BY.
Filtra grupos después de que GROUP BY los ha formado. Solo puede usarse con funciones agregadas. A diferencia de WHERE, actúa sobre grupos completos, no sobre filas individuales.
Concatena los valores de una columna dentro de cada grupo en una cadena de texto. Acepta un separador personalizado (SEPARATOR) y puede combinarse con DISTINCT para eliminar duplicados.
Modificador de GROUP BY que añade automáticamente filas de subtotales por nivel de agrupación y una fila de total general al final. Los subtotales se identifican porque sus columnas de agrupación aparecen como NULL.
Expresión condicional que evalúa casos en orden y devuelve el valor del primer caso que se cumple. Se cierra con END y puede asignarse a una columna nueva con AS. Equivale a un bloque if/elif/else en programación.
Consulta anidada dentro de un WHERE o SELECT que primero calcula un valor de resumen (como el promedio global) y luego lo usa como referencia en la consulta exterior.
SQL procesa las cláusulas en este orden interno: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT. No es el orden en que se escriben, sino el orden en que el motor los evalúa.
Contenido de la clase
De filas a resúmenes: qué hace una función agregada
Una consulta ordinaria devuelve una fila por cada fila de la tabla. Una función agregada hace lo contrario: toma todas las filas (o un subconjunto) y colapsa el resultado en un único valor. Eso lo convierte en la herramienta fundamental para responder preguntas como "¿cuántas películas hay?", "¿cuánto suma el coste total?" o "¿cuál es la duración media?".
Las cinco funciones agregadas básicas cubren la mayoría de los análisis numéricos. Todas se escriben después de SELECT, igual que cualquier otra columna, y pueden renombrarse con AS para que el resultado tenga un nombre legible.
COUNT: contar con precisión
COUNT tiene tres variantes y cada una cuenta cosas distintas. Elegir mal entre ellas es el error más frecuente cuando se trabaja con columnas que pueden tener nulos.
| Variante | Qué cuenta | Cuándo usarla |
|---|---|---|
| COUNT(*) | Todas las filas, incluidas las que tengan nulos | Contar registros totales de una tabla |
| COUNT(columna) | Solo las filas donde esa columna no es NULL | Verificar cuántos registros tienen ese dato |
| COUNT(DISTINCT columna) | Los valores únicos, eliminando duplicados | Saber cuántos valores distintos existen |
SUM, AVG, MIN y MAX
SUM acumula todos los valores numéricos de una columna. AVG calcula la media aritmética ignorando los nulos, lo que significa que los campos vacíos no arrastran el promedio hacia cero. MIN y MAX devuelven los extremos de una columna: funcionan con números, fechas y texto (orden alfabético), pero no con booleanos.
- SUM y AVG solo tienen sentido en columnas numéricas. Aplicarlas sobre texto provoca un error o un resultado incoherente.
- AVG ignora los nulos: si 100 filas tienen valor y 20 son NULL, el promedio se calcula sobre 100, no sobre 120.
- MIN y MAX en columnas de texto devuelven el valor más temprano y más tardío en el alfabeto, lo que puede ser útil para encontrar el primer y último nombre de una lista ordenada.
GROUP BY: analizar por segmentos
GROUP BY convierte el análisis de "toda la tabla" en "un análisis por cada grupo". En lugar de devolver el total de películas de toda la base de datos, puede devolver el total por clasificación, por año, por idioma o por cualquier otra columna.
Hay dos reglas que no tienen excepción. Si se ignoran, MySQL devolverá un error o un resultado incorrecto.
- Todas las columnas del SELECT que no sean funciones agregadas deben aparecer también en el GROUP BY. Si seleccionas "rating" y "COUNT(*)", tienes que agrupar por "rating".
- El orden de los grupos no está garantizado. Si necesitas los resultados en un orden concreto, añade siempre ORDER BY después del GROUP BY.
HAVING: filtrar grupos, no filas
WHERE filtra filas antes de que se formen los grupos. HAVING filtra grupos una vez ya están formados. La diferencia es importante: WHERE no puede referenciar funciones agregadas porque se ejecuta antes de que existan; HAVING sí puede, porque actúa después de GROUP BY.
| WHERE | HAVING | |
|---|---|---|
| Cuándo actúa | Antes de GROUP BY | Después de GROUP BY |
| Filtra | Filas individuales | Grupos completos |
| Puede usar funciones agregadas | No | Sí |
| Caso de uso típico | rating = 'PG' | COUNT(*) > 200 |
Un patrón habitual es combinar WHERE y HAVING en la misma consulta: WHERE reduce las filas antes de agrupar (más eficiente), y HAVING elimina los grupos que no interesan después de agregarse.
Funciones avanzadas: GROUP_CONCAT, WITH ROLLUP y CASE WHEN
Más allá de los cinco agregados básicos, SQL ofrece herramientas para construir reportes más expresivos. Las tres más útiles para análisis y presentación de datos son GROUP_CONCAT, WITH ROLLUP y CASE WHEN.
- GROUP_CONCAT: concatena todos los valores de una columna dentro de cada grupo en una sola cadena de texto, separados por el carácter que se indique. Con DISTINCT elimina los duplicados antes de concatenar. Es ideal para generar listas compactas en reportes.
- WITH ROLLUP: se añade al final del GROUP BY y genera automáticamente filas de subtotales por cada nivel de agrupación, más una fila de total general. Las columnas de agrupación aparecen como NULL en las filas de subtotal; IFNULL permite reemplazar esos NULL por una etiqueta legible.
- CASE WHEN: crea una nueva columna calculada en función de condiciones. La estructura es CASE WHEN condición THEN valor ... ELSE valor_por_defecto END. Se usa habitualmente para segmentar datos en categorías (alto/medio/bajo) o para reetiquetado.
El orden lógico de ejecución
SQL no ejecuta las cláusulas en el orden en que se escriben. El motor sigue un orden interno independiente de cómo esté redactada la consulta. Entender este orden explica por qué WHERE no puede filtrar por alias definidos en SELECT, y por qué HAVING debe ir después de GROUP BY.
- FROM: identifica la tabla o las tablas de origen.
- WHERE: filtra las filas que no cumplen la condición.
- GROUP BY: forma los grupos a partir de las filas que quedaron.
- HAVING: elimina los grupos que no cumplen la condición agregada.
- SELECT: calcula las columnas y los agregados del resultado final.
- ORDER BY: ordena las filas del resultado.
- LIMIT: recorta el número de filas devueltas.
Código y ejemplos
Las cinco funciones agregadas
-- COUNT: contar filas, valores no nulos y valores únicos
SELECT COUNT(*) AS total_filas,
COUNT(replacement_cost) AS con_coste,
COUNT(DISTINCT rating) AS ratings_unicos
FROM film;
-- SUM y AVG: suma y media de una columna numérica
SELECT SUM(replacement_cost) AS coste_total,
AVG(length) AS duracion_media
FROM film;
-- MIN y MAX: extremos de una columna
SELECT MIN(length) AS pelicula_mas_corta,
MAX(length) AS pelicula_mas_larga
FROM film; Todas las funciones agregadas se pueden combinar en un único SELECT. El resultado siempre es una sola fila cuando no hay GROUP BY.
GROUP BY con COUNT y AVG
-- Cuántas películas hay en cada clasificación
SELECT rating,
COUNT(*) AS total
FROM film
GROUP BY rating
ORDER BY total DESC;
-- Tarifa media de alquiler por clasificación
SELECT rating,
AVG(rental_rate) AS tarifa_media
FROM film
GROUP BY rating
ORDER BY tarifa_media DESC; La columna que no es un agregado (rating) debe aparecer en GROUP BY. ORDER BY permite ordenar por el agregado calculado.
HAVING: filtrar grupos por condición agregada
-- Solo las clasificaciones con más de 200 películas
SELECT rating,
COUNT(*) AS total
FROM film
GROUP BY rating
HAVING COUNT(*) > 200
ORDER BY total DESC;
-- Características especiales asociadas a películas más largas que la media
SELECT special_features,
AVG(length) AS duracion_media
FROM film
GROUP BY special_features
HAVING AVG(length) > 115
ORDER BY duracion_media DESC; HAVING se escribe después de GROUP BY y antes de ORDER BY. Solo puede contener condiciones que impliquen funciones agregadas.
CASE WHEN: segmentar datos en categorías
-- Segmentar películas en tres grupos por coste de reemplazo
SELECT CASE
WHEN replacement_cost < 15 THEN 'Bajo'
WHEN replacement_cost BETWEEN 15 AND 20 THEN 'Medio'
ELSE 'Alto'
END AS segmento_coste,
COUNT(*) AS cantidad,
AVG(rental_rate) AS tarifa_media,
AVG(length) AS duracion_media
FROM film
GROUP BY segmento_coste
ORDER BY cantidad DESC; CASE WHEN genera una nueva columna calculada que puede usarse directamente en GROUP BY. El alias asignado con END AS es el que se referencia después.
Errores comunes
Buenas prácticas
Ejercicios
- Usando la tabla film de Sakila, cuenta cuántas películas hay en total con COUNT(*) y cuántos tipos de clasificación distintos hay con COUNT(DISTINCT rating).
- Calcula la suma total del replacement_cost de todas las películas y la media de la duración (length). Renombra las columnas con AS.
- Obtén la película con menor y mayor duración usando MIN y MAX sobre la columna length.
- Agrupa las películas por rating y muestra cuántas hay en cada grupo (COUNT) y la tarifa media de alquiler (AVG de rental_rate). Ordena el resultado de mayor a menor por la tarifa media.
- Usa HAVING para mostrar solo las clasificaciones que tienen más de 190 películas.
- Usa CASE WHEN para segmentar las películas en "Corta" (length < 90), "Media" (90–120) y "Larga" (> 120). Muestra cuántas hay en cada segmento.
Checklist final
- Conozco las cinco funciones agregadas básicas: COUNT, SUM, AVG, MIN y MAX.
- Entiendo la diferencia entre COUNT(*), COUNT(columna) y COUNT(DISTINCT columna).
- Sé que AVG ignora los nulos al calcular el promedio.
- Puedo escribir una consulta con GROUP BY y sé que todas las columnas no agregadas del SELECT deben estar en GROUP BY.
- Entiendo la diferencia entre WHERE (filtra filas) y HAVING (filtra grupos).
- Conozco el orden lógico de ejecución: FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT.
- Sé crear columnas condicionales con CASE WHEN...THEN...ELSE...END.
¿Has terminado la clase?
Márcala como repasada y vuelve cuando quieras revisarla.