domingo, 15 de noviembre de 2020

SUBAGRUPAR

Puede darse el caso de que en una misma consulta, necesitemos obtener resultados agrupados en distintos niveles. Un ejemplo sobre la base de datos Neptuno:

Resumen de importe de pedidos agrupado por Categoría de producto.

Select First(Categorías.NombreCategoría) As Categoria,
       Round(Sum(T.Cantidad * T.PrecioUnidad * (1-T.Descuento)), 2) As Importe
From (
     (
     (
     Pedidos 
     Inner Join
     [Detalles de pedidos] As T On Pedidos.IdPedido = T.IdPedido 
     )
     Inner Join 
     Productos On T.IdProducto Productos.IdProducto
     )
     Inner Join
     Categorías On Productos.IdCategoría Categorías.IdCategoría
Group By Productos.IdCategoría

Pero si necesitamos, además del importe por categoría, obtener resultados parciales, por ejemplo, para alguno de los países a los que se envían pedidos, vamos a tener un dilema con la cláusula Group By, puesto que si añadimos País, perdemos la posibilidad de mostrar el importe total por Categoría.

Por supuesto hay formas de resolverlo:

1.     Utilizar una consulta de referencias cruzadas manteniendo la agrupación por Categoría. Los países los utilizaremos como encabezado de columna y emplearemos el operador In en la cláusula Pivot para restringir los resultados a los países que nos interese.

2.     Agrupar por Categoría y País. El total general por Categoría lo obtendremos con una subconsulta.

Propongo una tercera: incorporar una expresión dentro de la función de agregado, en este ejemplo Sum(), que filtre los resultado que procesa la función:

Select First(Categorías.NombreCategoría) As Categoria,
       Round(Sum(T.Cantidad * T.PrecioUnidad * (1-T.Descuento)), 2) As Importe,
       Round(Sum(T.Cantidad * T.PrecioUnidad * (1-T.Descuento) * Abs(Pedidos.PaísDestinatario = "Alemania")), 2) As [Importe (Alemania)],
       Round(Sum(T.Cantidad * T.PrecioUnidad * (1-T.Descuento) * Abs(Pedidos.PaísDestinatario = "Francia")), 2) As [Importe (Francia)]
From (
     (
     Pedidos
     Inner Join
     [Detalles de pedidos] As T On Pedidos.IdPedido = T.IdPedido
     )
     Inner Join
     Productos On T.IdProducto = Productos.IdProducto
     )
     Inner Join
     Categorías On Productos.IdCategoría = Categorías.IdCategoría
Group By Productos.IdCategoría

Ramon Poch. Terrassa a 15/11/2020.