Agrupando Registros con SQL Server 2008

Estaré habciendo mención en las próxima publicaciones de algunas de las nuevas funciones que nos trae SQL Server 2008, me he sentido motivado a escribir sobre los nuevos features de SQL Server 2008, debido al gran numero de preguntas que he recibido a mi correo personal, por lo cual estare listando las mas importantes.

Una característica nueva que tiene la nueva versión de SQL Server, es el nuevo operador GROUPING SETS, que ya existía en otros motores de base de datos tales como Oracle, el cual permite combinar consultas de agrupación distintas en una sola consulta.

Es bueno aclarar que el operador GROUPING SETS es una extensión de la cláusula estándar GROUP BY. Cuando no se requieren todas las agrupaciones posibles que se generan utilizando un operador ROLLUP o CUBE (que ya existían en SQL Server 2005), se debe utilizar GROUPING SETS para especificar sólo las agrupaciones que se deseen. O sea, gracias a GROUPING SETS obtenemos los niveles de agrupación deseados y además nos devuelve el subtotal para cada subconjunto de agrupación.


En pocas palabras podríamos decir que GROUPING SET es mas abarcativo y genérico que ROLLUP o CUBE. Generalmente consultas que usen este tipo de operadores están relacionadas con el análisis de datos, reporting y todo lo relacionado con el mundo la Intelegencias de Negocios.

Les recuero este nuevo operador no viene hacer magia y a solucionar un problema que no se podia solucionar, sino mas bien nos simplifica y optimiza nuestras consultas, por eso es lo importante del mismo, pero quiero aclarar que sin utilizar este operador podiamos generar o encontrar los mismos resultados en SQL Server, pero no con el performance que este nos brinda.


Probemos en una consulta, como siempre utilizare la base de datos de prueba de SQL Server AdventureWorks para realizar este ejemplo:


Lo primero que nos viene a la cabeza para resolver la parte de la agrupación casi siempre es hacer una consulta usando UNION ALL con tres consultas diferentes, una por cada agrupación, seria algo como esto:


Pero podríamos solucionarlo utilizando el operador GROUPING SET, seria algo como esto:



Ahora como podrán ver en este último ejemplo, además de usar el operador GROUPING SETS, hago uso de la función GROUPING en el ORDER BY, esto es para ordenar el resultado por Name y CountryRegionCode.

Esta función (que ya existía en SQL Server 2005), nos indica si una expresión de columna especificada en una lista GROUP BY es agregada o no. GROUPING devuelve 1 para agregado y 0 para no agregado, en el conjunto de resultados.

La ventaja del uso GROUPING SETS no está solo dada por simplificar sintácticamente las consultas, sino también en cuestiones de performance.

Hice unas pruebas para monitorear el uso de recursos (SET STATISTICS IO ON) con 90,000 registros en mi tabla y estos fueron los resultados:


Usando UNION ALL:Table ‘Sales.SalesTerritory’. Scan count 3, logical reads 1728, physical reads 6, read-ahead reads 590, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.


Usando GROUPING SETS:Table ‘Sales.SalesTerritory’. Scan count 1, logical reads 576, physical reads 6, read-ahead reads 590, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Como se puede ver, GROUPING SETS hace menor uso de recursos de I/O. Esto se debe a que usando la nueva característica de SQL Server, el motor necesita leer menos paginas de datos, ya que hace el cálculo de agregación de más alto nivel sobre las agregaciones de menor nivel.

No Response to "Agrupando Registros con SQL Server 2008"

Publicar un comentario