Agrupamientos – Group By – Filtros Having

Agrupamientos en Select  – Usando Group by

Los agrupamientos en SQL Server se utilizan cuando en un listado existen funciones de agregado en algunos campos con campos que no las tienen.

Generalmente los agrupamientos se utilizan para mostrar resultados estadísticos con datos de varias tablas (Ver Joins). También en muchas ocasiones se puede hacer el listado usando Subconsultas. Puede usar el Plan de ejecución para analizar cual de las opciones es la mejor según el diseño de las tablas utilizadas.

Ejercicios

Usando Northwind
use Northwind
go

1. — Listar las categorías y la cantidad de productos que tiene. Usando Subconsultas. (Ver Subconsultas)

Primero, para saber cuantos productos hay de una categoría, por ejemplo para la Categoría 1
select Count(P.CategoryID) As ‘Cantidad de Productos’ from Products As P where P.CategoryID = 1
go

La instrucción anterior se incluye en el listado y cambiar el número de la categoría que se utilizó como ejemplo por el campo de Categorías.
Select C.CategoryID As ‘Código’, C.CategoryName As ‘Categoría’,  (select Count(P.CategoryID) from Products As P
where P.CategoryID = C.CategoryID) As ‘Cantidad de Productos’ from Categories As C
go

 Usando Agrupamientos
Select C.CategoryID As ‘Código’, C.CategoryName As ‘Categoría’,  Count(P.CategoryID) As ‘Cantidad de Productos’
from Categories As C
join Products As P on C.CategoryID = P.CategoryID
group by C.CategoryID, C.CategoryName
go
— Note que los campos que no tienen función de agregado debe incluirse en la cláusula Group By.




2.– Listado de los empleados y la cantidad de órdenes generadas y el monto total de las ordenes

select Empleado = E.LastName + SPACE(1) + E.FirstName,
Count(O.OrderID) As ‘Cantidad de Órdenes’,
Sum(O.Freight) As ‘Monto total’
from Orders As O
join Employees As E on O.EmployeeID = E.EmployeeID
Group by E.LastName + SPACE(1) + E.FirstName
go

3. — Ordenar la orden anterior por cantidad de órdenes

select Empleado = E.LastName + SPACE(1) + E.FirstName,
Count(O.OrderID) As ‘Cantidad de Órdenes’,
Sum(O.Freight) As ‘Monto total’
from Orders As O
join Employees As E on O.EmployeeID = E.EmployeeID
Group by E.LastName + SPACE(1) + E.FirstName
order by [Cantidad de Órdenes] desc
go

4. — Para listar los que tienen más de 100 órdenes únicamente. Se utiliza en filtrado con Having

select Empleado = E.LastName + SPACE(1) + E.FirstName,
Count(O.OrderID) As ‘Cantidad de Órdenes’,
Sum(O.Freight) As ‘Monto total’
from Orders As O
join Employees As E on O.EmployeeID = E.EmployeeID
Group by E.LastName + SPACE(1) + E.FirstName
having Count(O.OrderID) > 100
order by [Cantidad de Órdenes] desc
go

5. — Los productos de categorías 3,5,6 y 8 y la cantidad vendida de cada uno, incluir el código y descripción de la categoría

El diagrama muestra las relaciones de las tablas a utilizar.


select P.ProductID As ‘Cód. Producto’, P.ProductName As ‘Descripción’, SUM(OD.Quantity) As ‘Cantidad Vendida’, C.CategoryID As ‘Cód. Categoría’,
C.CategoryName As ‘Nombre Categoría’
from Products As P
join [Order Details] As OD on P.ProductID = OD.ProductID
join Categories As C on P.CategoryID = C.CategoryID
where C.CategoryID in (3,5,6,8)
Group by P.ProductID, P.ProductName, C.CategoryID, C.CategoryName
order by C.CategoryID asc, [Cantidad Vendida] desc
go

6. — Si se desea filtrar por la cantidad vendida, por ejemplo, productos con mas de 600 unidades vendidas.

select P.ProductID As ‘Cód. Producto’, P.ProductName As ‘Descripción’,
SUM(OD.Quantity) As ‘Cantidad Vendida’, C.CategoryID As ‘Cód. Categoría’,
C.CategoryName As ‘Nombre Categoría’
from Products As P
join [Order Details] As OD on P.ProductID = OD.ProductID
join Categories As C on P.CategoryID = C.CategoryID
where C.CategoryID in (3,5,6,8)
Group by P.ProductID, P.ProductName, C.CategoryID, C.CategoryName
Having SUM(OD.Quantity) > 600
order by C.CategoryID asc, [Cantidad Vendida] desc
go

Note la figura siguiente donde se destaca los bloques donde están las categorías y los valores menores en la cantidad que cumplen con el filtro de la cláusula Having.