Leccion 10 - Agregaciones y agrupaciones con GROUP BY
Tiempo estimado de lectura: 6 minutos
Con SQL podemos no solo listar datos de una tabla, tambien podemos agregar resultados. Esto significa, que podemos calcular sumas, maximos y minimos entre otro tipo de operaciones en el tiempo que consultamos datos con SELECT.
Agregaciones
Imagina que tenemos una tabla de Ventas con campos IdVenta, IdCliente, IdProducto, Cantidad e Importe. Supongamos que queremos calcular el total del importe de las ventas. La manera de obtener la suma del importe sobre la tabla Ventas seria la siguiente.
SELECT SUM(Importe)
FROM Ventas
El resultado seria el valor total del importe de las ventas. Facil verdad?
En SQL a la hora de hacer calculos podemos utilizar ademas de SUM()
, otras funciones como COUNT()
, MIN()
, MAX()
, AVG()
. Estas serian las funciones de agregaciones mas basicas.
Asi,
SELECT COUNT(IdVenta)
FROM Ventas
Nos devolveria el valor del numero de total de ventas, contando asi el numero de registros de cada venta realizada.
La consulta,
SELECT SUM(Importe)
FROM Ventas
Calcularia la suma del importe total sobre las ventas. Fijate en que esta vez indicamos el la funcion SUM() el campo Importe, el cual es la columna que proporciona los valores de los importes realizados,
SELECT MAX(Importe)
FROM Ventas
La consulta anterior nos proporciona el valor del importe maximo de las ventas realizadas. Asi al contrario,
SELECT MIN(Importe)
FROM Ventas
Nos devolveria el valor del importe minimo de las ventas realizadas.
Si lo que queremos calcular es la media de los importes de las ventas podemos utilizar AVG(). Por ejemplo,
SELECT AVG(Importe)
FROM Ventas
GROUP BY
Ahora te planteo lo siguiente, imagina quisieras saber cual es el producto que genera mas ventas, tanto en numero de ventas como en importe. Seria una pregunta muy interesante para un responsable de marketing. Para ello podemos agregar los resultados de COUNT y SUM a nivel de producto. Con SQL esto se hace de manera que añadirmos el campo del producto, de momento solo quedate con que en la tabla de ejemplo que venimos viendo en las lecciones, Ventas, tiene el campo IdProducto. Con lo siguiente obtendremos los resultados para la pregunta de negocio que hemos planteado.
SELECT IdProducto, COUNT(IdVenta) AS NumeroDeVentas, SUM(Importe) AS ImporteTotalVentas
FROM Ventas
GROUP BY IdProducto
Fijate que hemos añadido el campo IdProducto tanto en el select como a continuacion de la clausula GROUP BY. GROUP BY sirve para indicar en nuestra consulta cuales son los campos por los que queremos agrupar los resultados.
Si quisieramos agrupar ademas de por IdProducto por otros campos mas solo tenemos que añadir estos otros campos en la parte del SELECT
, para seleccionar que campos queremos que nos devuelva la consulta, y en la parte del GROUP BY
.
En la consulta de ejemplo anterior que nos sirve para agrupar el numero de ventas y el importe total de ventas a nivel de IdProducto, en si mismo IdProducto no es muy informativo, si quisieramos saber realmente el nombre del producto tendriamos que ir a la tabla Productos y comprobar el valor del nombre del producto que se corresponde con cada IdProducto. Sin embargo, esto con SQL es muy sencillo, si leiste la leccion anterior donde explicaba el uso de los distintos de JOIN
en SQL, a la hora de agrupar los resultados de una consulta, SQL nos permite poder relacionar los resultados y combinar datos entre las distintas tablas. De esta manera si queremos el nombre del producto en nuestra consulta simplemente tendriamos que hacer JOIN entre las tablas Ventas y Productos e incluir el campo Producto en el SELECT de nuestra consulta. Esto mismo es lo que haria la siguiente consulta.
SELECT b.Producto, COUNT(a.IdVenta) AS NumeroDeVentas , SUM(b.Importe) ImporteTotalVentas
FROM Ventas AS a
INNER JOIN Productos AS b ON b.IdProducto = a.IdProducto
GROUP BY b.Producto
Incluso un poco mas alla en el caso de que quisieramos ordenar nuestros datos por los productos que mas ventas han generado, para ello, tambien podemos utilizar ORDER BY en nuestra consulta. Te lo muestro a continuacion.
SELECT b.Producto, COUNT(a.IdVenta) AS NumeroDeVentas , SUM(b.Importe) ImporteTotalVentas
FROM Ventas AS a
INNER JOIN Productos AS b ON b.IdProducto = a.IdProducto
GROUP BY b.Producto
ORDER BY COUNT(a.IdVenta) DESC
HAVING BY
Filtrar datos en nuestras agrupaciones con SQL tambien es posible, pero no es lo que estas pensando, cuando vimos la cláusula WHERE aprendistre como filtrar datos, sin embargo esta vez necesitamos hacer algo diferente. Imagina el caso en el que queremos poder obtener el resultado de los productos que han vendido mas de 10 unidades, esto lo podemos hacer en nuestra consulta de la siguiente manera, introducimos la clausula HAVING BY.
SELECT b.Producto, COUNT(a.IdVenta) AS NumeroDeVentas , SUM(b.Importe) ImporteTotalVentas
FROM Ventas AS a
INNER JOIN Productos AS b ON b.IdProducto = a.IdProducto
GROUP BY b.Producto
HAVING BY COUNT(a.IdVenta) > 10
La clave de HAVING BY es que podemos filtrar los datos de la consulta en funcion de las agregaciones, que se aplica a los campos calculados con COUNT, SUM, MIN, MAX, etc. Si lo que quisieramos por otro lado es conocer el numero de ventas y el importe de un producto en concreto debemos utilizar WHERE, por ejemplo.
SELECT b.Producto, COUNT(a.IdVenta) AS NumeroDeVentas , SUM(b.Importe) ImporteTotalVentas
FROM Ventas AS a
INNER JOIN Productos AS b ON b.IdProducto = a.IdProducto
WHERE b.Producto = 'TV'
GROUP BY b.Producto
La consulta anterior filtra nuestros resultados mostrandonos las ventas y el importe total solo para el producto TV.