Responder preguntas de negocio como ¿cuánto vendemos por país? o ¿cuál es el ticket promedio por sucursal? requiere algo más que consultar fila por fila. La combinación de GROUP BY con funciones de agregación permite resumir millones de registros en resultados claros y accionables, y es la base de cualquier reporte profesional en SQL.
¿Cuál es la regla fundamental de GROUP BY?
La regla es directa: toda columna del SELECT que no sea una función de agregación debe aparecer en el GROUP BY [01:07]. Si una columna está en el SELECT pero no en el GROUP BY, la query simplemente falla. Este principio se repite a lo largo de cada consulta y es lo primero que debemos verificar antes de ejecutar.
Para demostrarlo, se presenta un ejemplo donde se quita deliberadamente una columna del GROUP BY [08:30]. El motor de base de datos detecta que falta una columna que no es agregación y arroja un error. Al volver a incluirla, la consulta funciona correctamente.
¿Cómo funciona COUNT para contar registros?
La función COUNT es la primera función de agregación que se explora. En su forma más simple, COUNT(*) cuenta todas las filas de una tabla [01:35]. Por ejemplo:
SELECT COUNT(*) AS total_clientes FROM Clientes devuelve cien registros en la tabla.
- Se pueden agregar múltiples conteos en una sola consulta, como contar clientes y contar teléfonos simultáneamente [02:05].
Combinando COUNT con GROUP BY se obtienen reportes muy útiles. Un GROUP BY básico agrupa por cliente_id y cuenta los pedidos de cada cliente [02:35]:
sql SELECT cliente_id, COUNT(*) AS cantidad_pedidos FROM Pedidos GROUP BY cliente_id ORDER BY cantidad_pedidos DESC LIMIT 10;
Esta consulta genera un top ten de pedidos por cliente. El resultado muestra, por ejemplo, que el cliente 81 tiene seis pedidos y el cliente 24 tiene cinco [03:15].
¿Cómo agrupar por fechas con EXTRACT?
Cuando se necesitan reportes temporales como pedidos por mes, se combinan funciones de fecha con GROUP BY [03:40]. La función EXTRACT(YEAR FROM fechaPedido) obtiene el año y EXTRACT(MONTH FROM fechaPedido) obtiene el mes:
sql SELECT EXTRACT(YEAR FROM fechaPedido) AS año, EXTRACT(MONTH FROM fechaPedido) AS mes, COUNT(*) AS pedidos_en_mes FROM Pedidos GROUP BY EXTRACT(YEAR FROM fechaPedido), EXTRACT(MONTH FROM fechaPedido) ORDER BY año, mes;
Estas funciones de fecha no son funciones de agregación, por lo tanto deben ir en el GROUP BY [04:25]. Un detalle importante: los nombres de las columnas deben coincidir exactamente con los de la tabla. En el ejemplo, el campo correcto es fechaPedido, no fecha [05:10].
El resultado muestra datos como: 2023, enero, ocho pedidos; 2023, febrero, cinco pedidos. Estos datos incluso se pueden visualizar con herramientas gráficas para observar tendencias [05:55].
¿Cómo usar SUM para sumar valores junto a COUNT?
Además de contar pedidos, resulta valioso saber cuánto representan en dinero. Para eso se utiliza la función SUM, que suma los valores de una columna numérica [06:30]:
sql SELECT EXTRACT(YEAR FROM fechaPedido) AS año, EXTRACT(MONTH FROM fechaPedido) AS mes, COUNT(*) AS pedidos_en_mes, SUM(total) AS total_pedidos FROM Pedidos GROUP BY EXTRACT(YEAR FROM fechaPedido), EXTRACT(MONTH FROM fechaPedido) ORDER BY año, mes;
Al ejecutar, cada fila muestra tanto la cantidad como el monto. Enero de 2023 tuvo ocho pedidos que sumaron 8,377.80, mientras que febrero tuvo cinco pedidos por 5,496.69 [07:25]. Se pueden combinar múltiples funciones de agregación (COUNT, SUM y otras) en una misma consulta sin necesidad de agregarlas al GROUP BY, porque las agregaciones son operaciones sobre los grupos, no columnas agrupadas.
¿Qué reportes puedes construir como práctica?
Como desafío se proponen tres reportes sobre la base de datos Tienda Latam [09:05]:
- Clientes activos por país: agrupar por país y contar donde
activo = true.
- Precio promedio y máximo por categoría: usar
AVG y MAX agrupando por categoría.
- Total de pedidos por mes: aplicar
EXTRACT(MONTH FROM ...) con COUNT.
Una verificación recomendada es comprobar que la suma de todos los grupos del primer reporte coincida con el total de registros donde activo = true. Comparte tus resultados en los comentarios y compara con otros estudiantes.