SUMMARIZE Vs GROUPBY Vs SUMMARIZECOLUMNS.
SUMMARIZE Vs GROUPBY Vs SUMMARIZECOLUMNS, estas tres funciones permiten crear una tabla de resumen en los datos, en el presente artículo discutiremos cuando se debe implementar cada una siguiendo buenas prácticas, adicionalmente comentaré algunas reflexiones generales.
— TABLA DE CONTENIDO DE ESTE ARTÍCULO
1. Cálculos en Tamaños de Grano Diferentes
a. Promedio Ingresos
b. Tabla Calculadas
c. Función SUMMARIZE
2. Funciones para Crear Tablas de Resumen
a. Función SUMMARIZECOLUMNS
b. Combinación ADDCOLUMNS/SUMMARIZE
c. Función GROUPBY
3. SUMMARIZE Vs GROUPBY Vs SUMMARIZECOLUMNS
a. Guía de Implementación Final
b. Bibliografía
Crear tablas de resumen es una utilidad muy poderosa, ya que, entre otras cosas, nos permite crear cálculos en un tamaño de grano diferente al nativo de la tabla de datos, es decir, nos prepara el camino para mostrar medidas en niveles de detalles distintos al que viene construida la base de datos.
Por ejemplo: Si nuestra tabla de origen tiene el detalle del día a día de las ventas, pero nosotros queremos mostrar en un reporte a lo largo los años, un agregado o cálculo a nivel de mes (por ejemplo: el promedio de ingresos), entonces, una opción clásica es crear una tabla de resumen como «pre-agregado» y luego generar la medida.
Con el párrafo anterior no estoy diciendo que sea la única manera de hacerlo, ni tampoco que se la mejor, no obstante, si estoy diciendo que es la vía más fácil para comprender este tipo de cálculos, sobre todo para quienes están iniciando en este magnífico mundo.
En apoyo a la nota recién realizada, hay que comentar que algunas soluciones en tamaños de grano diferentes son más elegantes, sin embargo, su entendimiento pleno requiere de más detalles y conceptos avanzados como: Tablas expandidas y Transición de contextos.
Cálculos en Tamaños de Granos Diferentes
La meta del presente artículo es dilucidar cuando implementar cada función de creación de tabla de resumen, es decir: SUMMARIZE, GROUPBY y SUMMARIZECOLUMNS, y establece una jerarquía de uso de cada una.
SUMMARIZE Vs GROUPBY Vs SUMMARIZECOLUMNS
Como el objeto de estudio para poder discernir estos casos de uso tienen como víctima los cálculos en tamaño de grano diferentes, vamos a dedicar unos párrafos para aterrizarlos así sea una pizca más.
Promedio Ingresos
Supongamos que tenemos los registros día a día de las ventas en una tabla denominada Pedidos:
Ahora bien, necesitamos presentar en una matriz con los años en filas el ingreso promedio, medida la cual llamaremos: PI, se logra fácilmente con la siguiente medida:
PI :=
AVERAGE ( Pedidos[Ingresos] )
La matriz luce:
Pero, no debemos perder de vista que dicha medida en realidad se lee:
Promedio de ingresos a nivel de día según el contexto.
Es decir, se lee el detalle más fino que nos proporciona la tabla Pedidos, por lo tanto, lo que se lee es el promedio ganado en un día. (En cuanto al contexto, puedes estudiar todos sus detalles en este artículo)
Empero, un requisito común consiste en:
Poder ver el promedio de ingresos a nivel de mes.
A razón de que en este caso que se desea observar a través de los años y tendría un buen significado verlo en una escala más grande.
— ¿Cómo abrazamos este objetivo?
El tamaño de grano es más grande, porque se debe pasar de día a mes, a menudo, cuando tenemos esta situación pensamos en crear una pre-agregado tabular o tabla de resumen.
Tablas Calculadas
Visualicémoslo desde una tabla calculada inicialmente para que se entienda mejor.
Resulta que la función por «excelencia» para crear una tabla de resumen es SUMMARIZE, nuestro ejemplo quedaría así:
PreAgregadoEnMes =
SUMMARIZE (
Pedidos;
Calendario[Mes Nombre];
«@Ing»; [Ingresos Tot]
)
Puedes estudiar a profundidad la función SUMMARIZE en este vídeo.
Conociendo cómo podemos crear la tabla de resumen la cual realiza el pre-agregado (SUM por la medida [Ingresos Tot]) al nivel deseado (mes) ya es viable crear nuestra medida, la cual denominaremos PIM_SUMMARIZE implementando la función AVERAGEX:
PIM_SUMMARIZE :=
AVERAGEX (
SUMMARIZE (
Pedidos;
Calendario[Mes Nombre];
«@Ing»; [Ingresos Tot]
);
[@Ing]
)
Nuestra matriz ahora luciría así:
Con esa brevísima introducción a Métricas en Tamaños de Grano Diferentes ya podemos ir al lío →
Funciones de Tabla de Resumen
Resulta que, para crear la tabla de resumen tenemos tres alternativas:
.
- SUMMARIZE
- SUMMARIZECOLUMNS
- GROUPBY
.
Función SUMMARIZECOLUMNS
Con la función SUMMARIZECOLUMNS podemos conseguir la misma tabla de resumen en una tabla calculada, de hecho, con una sintaxis más sencilla (Puede estudiar el ABC de SUMMARIZECOLUMNS en el minuto 1:32:00 del vídeo de SUMMARIZE) , he aquí la expresión:
PreAgregadoSmzColmns =
SUMMARIZECOLUMNS (
Calendario[Mes Nombre];
«@Ing»; [Ingresos Tot]
)
Y aunque podemos crear la medida sin ningún problema:
PIM_SUMMARIZECOLUMNS :=
AVERAGEX (
SUMMARIZECOLUMNS (
Calendario[Mes Nombre];
«@Ing»; [Ingresos Tot]
);
[@Ing]
)
Cuando la llevamos a la matriz, esta se daña indicando que no se puede mostrar el objeto visual:
Si pulsamos clic en ver detalles, este el mensaje de error:
No es que nosotros hayamos hecho algo mal, es que:
SUMMARIZECOLUMNS no puede ser llamada si un contexto de filtro externo ha activado la operación de transición de contextos.
En resumidas cuentas, SUMMARIZECOLUMNS en medida es de una implementación casi nula, a menos que se vaya a implementar única y exclusivamente en una simple tarjeta:
O matriz sin nada en las demás áreas de colocación (lo mismo aplica para los demás objetos visuales), dado que es una función diseñada y optimizada para realizar consultas.
Es decir, podemos plantear lo siguiente:
Si queremos crear una medida que implemente una tabla de resumen en la propia expresión, debemos utilizar la función SUMMARIZE por en encima de SUMMARIZECOLUMNS ya que no es compatible con la gran mayoría de los reportes.
Dicho de otro modo y por seguridad:
Si una tabla de resumen es requerida en una consulta o tabla calculada utilizar la función SUMMARIZECOLUMNS ya que es la función que tiene todo para generar este tipo de materialización, además es la más rápida, mucho más rápida que SUMMARIZE.
Si una tabla de resumen es requerida en una medida o columna calculada utilizar SUMMARIZE con las siguientes salvedades:
ADDCOLUMNS/SUMMARIZE
Siendo 100% transparente contigo, la verdad es que la expresión de la medida [PIM_SUMMARIZE], mejor dicho, esta:
PIM_SUMMARIZE :=
AVERAGEX (
SUMMARIZE (
Pedidos;
Calendario[Mes Nombre];
«@Ing»; [Ingresos Tot]
);
[@Ing]
)
Sigue malas prácticas e implementación obsoleto en la función SUMMARIZE (parcialmente):
Resulta que:
Como argumento y demostró Alberto Ferrari de SQLIBI.Com en el artículo: All the secrets of SUMMARIZE.
Artículo que sirve como espina dorsal para nuestro vídeo: SUMMARIZE en DAX: La Cruda Realidad.
Crear columnas calculadas temporales con SUMMARIZE es una muy mala idea dado que tiene serios problemas de rendimiento y seguir el hilo del comportamiento interno exacto es complejo por actualizaciones no documentadas en su totalidad y cambios en el algoritmo en diversas tecnologías de DAX.
De hecho, Alberto deja una nota en el 2018 que indica que el comportamiento interno expuesto en su artículo es obsoleto, porque dada las actualizaciones en enero del 2018 y posteriores cambian el comportamiento descrito.
En nuestro vídeo: SUMMARIZE en DAX: La Cruda Realidad, partimos de todo lo expuesto por Alberto, realizamos indagaciones adicionales y sobre todo: pasamos casi dos semanas de lleno en experimentación, tomando notas, planteando escenarios A/B, contrastando en diferentes suposiciones del algoritmo, para extrapolar el comportamiento comentado por Alberto Ferrari y brindarles una explicación del comportamiento interno de la función SUMMARIZE una pizca más «actualizada».
La última premisa es peligrosa y puede sonar pretensiosa, pero la verdad hicimos nuestro mejor esfuerzo, ya que consideramos que la operación de generación, aunque obsoleta, su estudio implica conceptos como: tablas expandidas, transición de contextos y data lienage que creemos ayudan afianzar a las personas que se meten de lleno en el dominio de DAX, pues, estos tres conceptos son claves en DAX general.
El punto es que:
Crear columnas calculadas temporales con SUMMARIZE es una mala práctica ya que tiene dos problemas principales: rendimiento y complejidad, además, al tener la alternativa ADDCOLUMNS/SUMMARIZE, la cual es más rápida en rendimiento y su algoritmo no cambia, es más, entender cómo funciona esta combinación es 10 veces más sencilla que SUMMARIZE por si sola,
Lleva a la conclusión que la operación de generación, es decir, del tercer parámetro en adelante se considere obsoleto.
Veamos como aparce en la función SUMMARIZE en DAX guide:
PERO CUIDADO:
Esto no quiere decir que la función este 100% obsoleta y haya dejado de tener soporte por parte de Microsoft o el equipo no trabaje en mejoras, si revisamos la documentación en Microsoft aquí, veremos que sigue documentada con normalidad, y no aparece una nota como sí aparecen en funciones de Excel como JERARQUÍA:
Todo, esto para comentarte que:
La función SUMMARIZE está obsoleta para la operación de generación, es decir, tercer parámetro en adelante, esto estriba en que la operación de agrupación NO está obsoleta, por ello, los dos primeros parámetros, además son seguros de utilizar y con un rendimiento adecuado.
Si tienes conocimiento y/o fuentes que Microsoft quiera dejar obsoleta en su totalidad la función SUMMARIZE, te pido muy amablemente que me cuentes en los comentarios.
El punto es que, nuestra expresión para la medida debe ser escrita con buenas prácticas de la siguiente manera:
PIM_SUMMARIZE/ADDCOLUMNS :=
AVERAGEX (
ADDCOLUMNS (
SUMMARIZE (
Pedidos;
Calendario[Mes Nombre]
);
«@Ing»; [Ingresos Tot]
);
[@Ing]
)
Corrobora que en la medida [PIM_SUMMARIZE/ADDCOLUMNS] utilizamos la zona no radioactiva, implementado los parámetros seguros, pero nos apoyamos de la función ADDCOLUMNS para añadir la columna temporal.
La combinación ADDCOLUMNS/SUMMARIZE puedes estudiarla a partir del minuto 1:24:05 de nuestro vídeo de SUMMARIZE.
— Espera …
Tenemos otra función de creación de tabla de resumen
Función GROUPBY
Con la función GROUPBY podemos conseguir el mismo resultado que con la combinación ADDCOLUMNS/SUMMARIZE, se puede corroborar en una tabla calculada:
PreAgregadoGROUPBY =
GROUPBY (
Pedidos;
Calendario[Mes Nombre];
«@Ing»; SUMX (
CURRENTGROUP ();
Pedidos[Ingresos]
)
)
Sigue una firma muy parecida a SUMMARIZE, a excepción del último parámetro que siempre se debe indicar con una función de iteración, por ejemplo: SUMX en lugar de SUM o AVERAGEX en lugar de AVERAGE y apoyados de la función CURRENTGROUP.
Por lo que nuestra tercera alternativa para la medida sería:
PIM_GROUPBY =
AVERAGEX (
GROUPBY (
Pedidos;
Calendario[Mes Nombre];
«@Ing»; SUMX (
CURRENTGROUP ();
Pedidos[Ingresos]
)
);
[@Ing]
)
GROUPBY no tiene ningún problema en la matriz:
— Entonces:
¿Por qué no desechar completamente SUMMARIZE y utilizar GROUPBY?
Porque en primera instancia GROUPBY nació para reemplazar a SUMMARIZE en unos casos muy específicos, en agrupaciones avanzadas, en particular:
Cuando necesitemos agregar una columna de un resultado de SUMMARIZE, visto en otro ángulo, en anidación de tablas de resumen se debe optar por GROUPBY debido a que SUMMARIZE no soporta esta operación.
Este no es un artículo para estudiar GROUPBY, no obstante, puedes estudiar más en el artículo de Marco Russo: Nested Grouping using GROUPBY Vs SUMMARIZE o en el capítulo 4 del libro de Philip Semark titulado Beginning DAX With Power BI. o el capítulo 7 del título Pro DAX With Power BI del mismo autor.
El rendimiento de GROUPBY es menor que la función SUMMARIZE, haciendo algunas pruebas sencillas y rápidas de rendimiento para nuestras medidas [PIM_ADDCOLUMNS/SUMMARIZE] y [PIM_GROUPBY] en DAX Studio encontramos:
No en todos los casos GROUPBY tiene un menor rendimiento, a pesar de ello, en la mayoría que he encontrado SUMMARIZE supera, por lo que la considero la opción por defecto, luego en etapas de optimización podemos empezar a plantear alternativas de la misma expresión y realizar las distintas pruebas de rendimiento.
— Entonces, ¿El resultado de esta batalla?
SUMMARIZE Vs GROUPBY Vs SUMMARIZECOLUMNS
Después de lo descrito a lo largo de este artículo, y de las diversas conclusiones que nos proporcionan la comunidad de expertos en DAX, llegamos a lo siguiente:
Guía de Implementación Final (SUMMARIZE Vs GROUPBY Vs SUMMARIZECOLUMNS)
Si una tabla de resumen es requerida en una consulta o tabla calculada utilizar la función SUMMARIZECOLUMNS.
Si una tabla de resumen es requerida en una medida o columna calculada utilizar SUMMARIZE con la siguientes salvedades:
— Si se requiere nuevas columnas temporales, implementar la combinación SUMMARIZE/ADDCOLUMNS, si no, como es evidente, basta con sólo SUMMARIZE.
—Implementar SUMMARIZE o la combinación ADDCOLUMNS/SUMMARIZE por defecto, puesto que, con mayor frecuencia (pero no siempre) arroja mejor tiempo de repuesta comparado con su par GROUPBY, no obstante, crear en fase de optimización la expresión equivalente con GROUPBY y comprobar cuál es más eficiente es el criterio y final.
Si se requiere anidación de resultado de tablas de resumen o agrupaciones avanzadas utilizar GROUPBY, ya que lo permite en contraste con SUMMARIZE que carece de esta habilidad.
Así culmina esta batalla.
Bibliografía
.
- SQLBI, Todos los Secretos de SUMMARIZE [Ir →]
- SQLBI, Buenas Prácticas Utilizando ADDCOLUMNS y SUMMARIZE [Ir →]
- SQLBI, Agrupaciones Anidadas utilizando GROUPBY Vs SUMMARIZE [Ir →]
- SQLBI, Introducción a SUMMARIZECOLUMNS [Ir →]
- MICROSOFT, Función SUMMARIZE [Ir →]
- CHRIS WEEB’S BLOG, DAX Query 1 – 3 [Ir →]
- BEGINNING DAX WITH POWER BI, Capítulo 4 [Ir →]
- PRO DAX WITH POWER BI, Capítulo 7 [Ir →]
.
Eso es todo por ahora con el artículo.
Por favor, comenta y regálame tu feedback, sugerencias, correcciones, etc. Qué cosas o elementos se me escapan y cuáles datos adicionales pueden complementar esta guía, cuáles son tus comentarios, experiencias, etc.
Estaré leyendo y respondiendo todos los comentarios activamente.
— Miguel Caballero