Con SQL básico listás filas: «dame todos los pedidos». Pero muchas veces no querés la lista, sino un resumen: «¿cuántos pedidos hay?», «¿cuánto se vendió en total?», «¿cuál es el importe promedio?». Eso lo hacen las funciones de agregación, que toman muchas filas y devuelven un solo valor: COUNT (cuenta filas), SUM (suma), AVG (promedio), MAX y MIN. El paso siguiente es GROUP BY: en vez de un resumen global, uno por categoría. «¿Cuánto vendió cada vendedor?» agrupa los pedidos por vendedor y suma dentro de cada grupo. Y hay una distinción que causa mucha confusión: WHERE filtra filas antes de agrupar (qué pedidos entran en el cálculo), mientras que HAVING filtra grupos después de agregar (qué resultados agrupados mostrar). Por ejemplo: «vendedores cuyo total supere 10.000» se filtra con HAVING, no con WHERE, porque ese total solo existe después de agrupar. Dominar agregaciones y GROUP BY es el salto de consultar datos a analizarlos, y es la base de cualquier informe o panel.
Ver índice de contenidos
Las funciones de agregación
Una función de agregación toma un conjunto de filas y las resume en un solo valor. Es lo contrario de listar: en vez de devolver muchas filas, devuelve una respuesta calculada sobre todas ellas. Las cinco esenciales:
| Función | Qué calcula |
|---|---|
COUNT() | Cuántas filas hay |
SUM() | La suma de una columna numérica |
AVG() | El promedio |
MAX() / MIN() | El valor máximo / mínimo |
-- Un solo valor resumen sobre toda la tabla
SELECT COUNT(*) FROM pedidos; -- ¿cuántos pedidos hay?
SELECT SUM(importe) FROM pedidos; -- ¿cuánto se vendió en total?
SELECT AVG(importe) FROM pedidos; -- ¿importe promedio?De muchas filas a una respuesta
Sin agregación, SELECT importe FROM pedidos devuelve miles de filas. Con agregación, SELECT SUM(importe) FROM pedidos devuelve una: el total. Ese cambio —de la lista al número— es el que convierte los datos en información útil para tomar decisiones.
Agrupar con GROUP BY
La agregación sola da un resumen global. Pero casi siempre querés el resumen por categoría: no «cuánto se vendió en total», sino «cuánto vendió cada vendedor». Ahí entra GROUP BY: agrupa las filas que comparten un valor y aplica la agregación dentro de cada grupo.
-- Total vendido por cada vendedor
SELECT vendedor, SUM(importe) AS total
FROM pedidos
GROUP BY vendedor;
-- Cuántos pedidos hizo cada cliente (combinando con JOIN)
SELECT clientes.nombre, COUNT(pedidos.id) AS n_pedidos
FROM clientes
LEFT JOIN pedidos ON pedidos.cliente_id = clientes.id
GROUP BY clientes.nombre;La regla mental: lo que ponés en GROUP BY es la categoría (una fila de resultado por cada valor distinto), y la agregación es lo que calculás dentro de cada una. Combinado con JOIN, permite resumir datos repartidos en varias tablas.
WHERE vs HAVING
Esta es la distinción que más confunde, y entenderla resuelve la mayoría de los errores con GROUP BY. Ambos filtran, pero en momentos distintos:
WHEREfiltra filas antes de agrupar. Decide qué filas entran en el cálculo. Ejemplo: «solo los pedidos de este año».HAVINGfiltra grupos después de agregar. Decide qué resultados agrupados mostrar, según el valor calculado. Ejemplo: «solo los vendedores cuyo total supere 10.000».
SELECT vendedor, SUM(importe) AS total
FROM pedidos
WHERE fecha >= '2026-01-01' -- 1. filtra filas: solo pedidos de este año
GROUP BY vendedor -- 2. agrupa por vendedor
HAVING SUM(importe) > 10000; -- 3. filtra grupos: solo los que sumen > 10.000Si intentás WHERE SUM(importe) > 10000, la base de datos da error. La razón es el orden: WHERE se evalúa antes de que exista ningún grupo ni ninguna suma —en ese momento solo hay filas sueltas, y el «total del vendedor» todavía no se ha calculado—. Por eso, cualquier condición que dependa de un valor agregado (un total, un conteo, un promedio) tiene que ir en HAVING, que actúa después de agrupar. Regla simple: filtro sobre filas individuales → WHERE; filtro sobre resultados agrupados → HAVING.
Errores frecuentes
- Usar WHERE con una agregación. Da error; las condiciones sobre totales van en HAVING.
- Seleccionar columnas que no están en GROUP BY. Debe ir en el GROUP BY o dentro de una agregación; si no, es ambiguo.
- Confundir COUNT(*) con COUNT(columna). El segundo no cuenta las filas con valor vacío en esa columna.
- Olvidar que las agregaciones ignoran los NULL. AVG y SUM no cuentan los vacíos; puede alterar el resultado.
- Agrupar sin necesidad. Si querés un solo total global, no hace falta GROUP BY.
- Contar mal tras un JOIN uno-a-muchos. Las filas se multiplican; usar COUNT/SUM con cuidado o DISTINCT.
- Poner el HAVING donde va el WHERE. Filtrar filas individuales con HAVING funciona a veces pero es menos eficiente y confuso.
Preguntas frecuentes
¿Qué son las funciones de agregación en SQL?
Las funciones de agregación son funciones de SQL que toman un conjunto de muchas filas y las resumen en un solo valor calculado, en lugar de devolver las filas individuales. Representan lo contrario de una consulta que lista datos: mientras que una consulta normal devuelve una fila por cada registro que cumple la condición, una función de agregación procesa todas esas filas juntas y produce un único resultado que las resume. Las funciones de agregación más importantes y usadas son cinco. La función de conteo cuenta cuántas filas hay, y es útil para saber, por ejemplo, cuántos pedidos existen. La función de suma calcula el total de una columna numérica, como el importe total vendido. La función de promedio calcula la media de una columna numérica, como el importe medio de los pedidos. Y las funciones de máximo y mínimo devuelven, respectivamente, el valor más alto y el más bajo de una columna, como el pedido más caro o más barato. El valor de estas funciones es que transforman grandes cantidades de datos en respuestas concretas y accionables: en vez de obtener una lista de miles de importes, se obtiene directamente el total, el promedio o el conteo, que es lo que realmente se necesita para tomar decisiones, elaborar informes o construir paneles. Las funciones de agregación son, por tanto, el primer paso para pasar de simplemente consultar datos a analizarlos, y se vuelven aún más potentes cuando se combinan con la agrupación por categorías, que permite calcular esos resúmenes no de forma global sino separados por grupos.
¿Para qué sirve GROUP BY?
GROUP BY sirve para calcular resúmenes no de forma global sobre toda la tabla, sino separados por categorías, agrupando las filas que comparten un mismo valor y aplicando una función de agregación dentro de cada grupo. La necesidad de GROUP BY surge de que, muy a menudo, un resumen global no es suficiente y lo que se quiere es un resumen desglosado. Por ejemplo, en lugar de saber cuánto se ha vendido en total, interesa saber cuánto ha vendido cada vendedor; en lugar de cuántos pedidos hay en total, cuántos pedidos ha hecho cada cliente; en lugar del importe promedio general, el importe promedio por categoría de producto. GROUP BY resuelve exactamente esto: se le indica por qué columna agrupar, que es la categoría, y la base de datos reúne todas las filas que comparten el mismo valor en esa columna formando grupos, para luego aplicar la función de agregación por separado a cada grupo, devolviendo una fila de resultado por cada categoría distinta con su valor resumen correspondiente. La forma intuitiva de pensarlo es que la columna que se pone en GROUP BY define las categorías, es decir, habrá una fila de resultado por cada valor distinto de esa columna, y la función de agregación define qué se calcula dentro de cada categoría. GROUP BY se combina muy frecuentemente con las uniones entre tablas, lo que permite resumir datos que están repartidos en varias tablas, como contar cuántos pedidos tiene cada cliente uniendo la tabla de clientes con la de pedidos. Es una de las herramientas más potentes de SQL para el análisis de datos, ya que convierte un conjunto de registros detallados en un resumen estructurado y significativo por categorías.
¿Cuál es la diferencia entre WHERE y HAVING?
La diferencia entre WHERE y HAVING es una de las que más confusión genera al aprender SQL, y entenderla resuelve la mayoría de los problemas con las consultas de agrupación. Ambas cláusulas sirven para filtrar, pero actúan en momentos distintos del procesamiento de la consulta y sobre cosas distintas. WHERE filtra las filas individuales antes de que se realice la agrupación, es decir, decide qué filas entran a formar parte del cálculo; por ejemplo, quedarse solo con los pedidos de este año antes de agruparlos y sumarlos. HAVING, en cambio, filtra los grupos ya formados y resumidos después de aplicar las funciones de agregación, es decir, decide qué resultados agrupados se muestran en función del valor calculado; por ejemplo, quedarse solo con los vendedores cuyo total de ventas supere una cierta cantidad. La clave para entenderlo es el orden de las operaciones: primero WHERE selecciona las filas, luego GROUP BY forma los grupos, después se calculan las agregaciones de cada grupo, y finalmente HAVING filtra esos grupos según sus valores agregados. De ahí se deriva la regla fundamental: una condición que se basa en un valor agregado, como un total, un conteo o un promedio, debe ir necesariamente en HAVING y no en WHERE, porque en el momento en que WHERE se evalúa esos valores agregados todavía no existen, ya que aún no se ha agrupado nada. Intentar usar WHERE con una función de agregación produce un error precisamente por esta razón. La regla práctica es simple: si el filtro se aplica sobre las filas individuales, se usa WHERE; si el filtro se aplica sobre los resultados ya agrupados, se usa HAVING.
¿Por qué me da error usar SUM en un WHERE?
Usar una función de agregación como la suma dentro de una cláusula WHERE produce un error porque contradice el orden en que la base de datos procesa las distintas partes de una consulta. La cláusula WHERE se evalúa en una etapa temprana del procesamiento, cuando la base de datos está examinando las filas individuales una por una para decidir cuáles conservar, y en ese momento todavía no se ha realizado ninguna agrupación ni se ha calculado ningún valor agregado. Es decir, cuando WHERE se ejecuta, conceptualmente aún no existe la noción de un total por vendedor ni de un conteo por categoría, porque los grupos y sus resúmenes se forman en una etapa posterior. Por eso, pedirle a WHERE que filtre por el resultado de una suma es pedirle que use algo que todavía no se ha computado, lo que la base de datos rechaza con un error. La solución es utilizar la cláusula HAVING en lugar de WHERE para las condiciones que dependen de valores agregados, ya que HAVING se evalúa después de que se hayan formado los grupos y calculado sus agregaciones, momento en el que el total, el conteo o el promedio ya existen y pueden usarse como criterio de filtrado. Así, una condición como quedarse con los vendedores cuyo total de ventas supere cierta cantidad se expresa correctamente en HAVING. Comprender esta distinción no solo evita el error, sino que refuerza la comprensión del modelo mental correcto de cómo se procesa una consulta SQL: primero se filtran filas con WHERE, luego se agrupan con GROUP BY, después se agregan, y finalmente se filtran los grupos con HAVING.
¿Las agregaciones tienen en cuenta los valores vacíos?
El tratamiento de los valores vacíos, es decir los valores nulos que representan la ausencia de dato, por parte de las funciones de agregación es un detalle importante que puede causar confusión y resultados inesperados si no se conoce. La regla general es que la mayoría de las funciones de agregación ignoran los valores nulos, es decir, no los tienen en cuenta en su cálculo. Por ejemplo, la función de suma suma solo los valores que existen y omite los nulos, la función de promedio calcula la media considerando únicamente las filas que tienen un valor real y sin contar los nulos ni en el numerador ni en el número de elementos, y las funciones de máximo y mínimo ignoran igualmente los nulos. Esto tiene consecuencias prácticas que conviene tener presentes: por ejemplo, un promedio puede diferir de lo esperado si hay muchas filas con valor vacío, ya que esas filas simplemente no participan en el cálculo, y no se tratan como ceros. El caso del conteo merece una mención especial, porque tiene dos variantes con comportamientos distintos. Cuando se cuenta usando el asterisco, se cuentan todas las filas del grupo, incluidas las que tienen valores nulos en cualquier columna, porque se cuentan filas y no valores de una columna concreta. En cambio, cuando se cuenta una columna específica, solo se cuentan las filas en las que esa columna tiene un valor real, ignorando las que la tienen vacía. Esta diferencia entre contar todas las filas y contar los valores presentes de una columna es sutil pero importante, y elegir la variante equivocada puede llevar a resultados incorrectos. Por eso, al trabajar con agregaciones sobre columnas que pueden contener valores vacíos, conviene tener siempre presente cómo cada función trata esos nulos.
¿Puedo combinar GROUP BY con JOIN?
Sí, combinar la agrupación con las uniones entre tablas es una de las técnicas más habituales y potentes en el análisis de datos con SQL, ya que permite resumir información que está repartida en varias tablas relacionadas. El patrón típico consiste en unir primero las tablas necesarias para reunir en una misma consulta los datos que se quieren analizar, y luego agrupar y agregar sobre el resultado de esa unión. Por ejemplo, para saber cuántos pedidos ha hecho cada cliente, se une la tabla de clientes con la de pedidos mediante su relación de clave, y después se agrupa por cliente y se cuentan los pedidos de cada uno; o para conocer el total facturado por categoría de producto, se unen las tablas correspondientes y se agrupa por categoría sumando los importes. Esta combinación es muy poderosa porque aprovecha a la vez la capacidad de las uniones para relacionar datos dispersos y la de la agrupación para resumirlos por categorías. Sin embargo, hay que tener una precaución importante cuando la unión es de tipo uno a muchos, en la que una fila de una tabla se relaciona con varias de la otra: en ese caso, la unión multiplica las filas, repitiendo los datos del lado uno tantas veces como coincidencias haya en el lado muchos, lo que puede provocar que los cálculos de agregación cuenten o sumen valores duplicados y produzcan resultados inflados si no se tiene cuidado. Para manejar correctamente estas situaciones se recurre a técnicas como contar valores distintos cuando corresponde, estructurar la consulta con subconsultas, o elegir cuidadosamente qué se agrega. Además, al usar uniones de tipo LEFT para conservar todas las filas de una tabla aunque no tengan coincidencias, conviene tener presente cómo se cuentan los grupos sin datos asociados. Bien aplicada, la combinación de agrupación y uniones es la base de la mayoría de los informes y análisis relacionales.
Fuentes
Documentación oficial y material de la comunidad consultados para esta guía. Fecha de consulta: 28 de julio de 2026.
Aportes de la comunidad Underc0de
- Underc0de, foro. Sección Bases de datos. Consultas y análisis.
- Underc0de, blog. Blog de la comunidad. Artículos de datos.
Documentación oficial
- PostgreSQL. Aggregate Functions. Funciones de agregación oficiales.
- MySQL. GROUP BY y agregaciones. Referencia oficial.
- SQLite. Aggregate Functions. Documentación de agregaciones.
- ISO/IEC. SQL (ISO/IEC 9075). El estándar del lenguaje.