DAX: Columnas calculadas vs Medidas – II

Este escrito forma parte de la serie: Escenarios de Modelado con DAX

Algunos de los recursos que he consultado sobre Modelado tabular y DAX los podemos encontrar en Modelos tabulares y DAX – Recursos

Muchísima gente que llega al mundo del DAX con Power BI viene de la mano de Excel y las Tablas dinámicas. Eso está muy bien, hay mucha experiencia que es posible reutilizar para trabajar con el modelo tabular y DAX y particularmente con Power BI.

Lo que sucede es que ahora, al trabajar con Modelos tabulares, llega el momento de pensar de una forma un tanto diferente. Especialmente a la hora de decidir entre Columnas calculadas y Medidas.

Aspectos que tienen en común las columnas calculadas y las medidas:

  • Misma sintaxis para escribir expresiones DAX
  • Misma Barra de fórmulas con mismo Intellisense y conjunto de funciones a su disposición
  • Mismo objetivo, enriquecer el Modelo tabular que ha sido cargado al procesar las consultas.

En días anteriores vimos cómo crear Columnas calculadas en Modelos tabulares con DAX y hablamos de algunos inconvenientes. Mejor repito este fragmento, es muy importante.

Implicación de crear columnas calculadas para Modelos Tabulares

Voy a resumir algunos de los aspectos a tener en cuenta cuando se crea una columna calculada:

  • Se evalúa la expresión para cada una de las filas de la tabla
  • Durante la evaluación se crea algo que conoceremos luego como Contexto de fila, que permite al motor conocer el valor exacto de cada columna involucrada en la expresión a evaluar
  • Se almacena el resultado correspondiente en cada una de las filas de la tabla
  • No se aplica ninguna acción de filtrado en este momento, no existe lo que luego conoceremos como Contexto de Filtro
  • En el proceso de escritura de la expresión DAX, encontramos que, sin utilizar funciones de relaciones o navegación, no es posible ver columnas fuera de la tabla actual.
  • En materia de procesamiento de Modelo Tabular, las columnas calculadas se procesan una vez procesadas todas las tablas que vienen de las consultas o de expresiones DAX que devuelven tablas al modelo. Durante el procesado de las nuevas columnas calculadas no es posible aplicar los algoritmos de optimización que resultan muy eficientes en la primera fase.
  • Para colmo de males:
    • El resultado puede ser incorrecto, tal y como hemos visto hoy. No es posible utilizar columnas calculadas para todo. En caso de ratios o porcientos de contribución al padre, no es posible.
    • Y en otros casos, puede parecer que está bien; pero luego el resultado es incorrecto si se aplican filtros que no afectan a la tabla en cuestión.

Para dar a solución a todos estos escenarios, podemos y debemos trabajar con Medidas, creadas con expresiones DAX para enriquecer los Modelos tabulares, que es nuestro objetivo.

Antes, creamos tres columnas calculadas, que realizaron los siguientes cálculos:

Importe Ventas = Ventas[CantidadETL] * Ventas[Precio]
Beneficios = Ventas[CantidadETL] * (Ventas[Precio] – Ventas[Coste])
% Beneficios = DIVIDE(Ventas[Beneficios];Ventas[Importe Ventas];0)

Recuerdo la imagen que obtuvimos como resultado

ColCalMal

Hoy vamos a crear las medidas que cumplan con los requisitos de negocio y que eviten todos los inconvenientes de las columnas calculadas.

Hay que tener en cuenta que:

  • Como la medida no pertenece a ninguna tabla en concreto, no puede acceder, por sí misma a las filas de las columnas de ninguna de las tablas.
  • No existe, de forma natural, el contexto de fila, como en las columnas calculadas.
  • La buena noticia es que DAX dispone de funciones, que son iteradores, que recorren una tabla o expresión DAX que devuelva tabla y se pase a la función como primer parámetro, y fila a fila de esa tabla evalúa la expresión que se pase como segundo parámetro.

Como siempre, veamos la teoría a través de ejemplos.

Para calcular Importe Ventas con una medida DAX, lo que en realidad necesitamos es recorrer la tabla Ventas y poder calcular, fila a fila la expresión Ventas[CantidadETL] * Ventas[Precio]. Luego, hay que sumar estos valores para obtener el resultado agregado.

Medidas en Modelos tabulares

Una de las opciones es seleccionar la tabla _Cálculos, el contenedor para medidas que creamos en la entrada anterior, DAX: Crear contenedor para medidas DAX en Modelos tabulares con Power BI,  y en los tres puntos que aparecen a la derecha desplegar las opciones y seleccionar Nueva Medida. Para que se note la diferencia en el informe, las tres medidas que voy a crear van a empezar con la palabra Total.

En la barra de fórmulas, escribimos el nombre y vemos que, al intentar sumar la expresión, no podemos. La función SUM sólo permite trabajar con una columna.

SumNoVale

Afortunadamente, disponemos de SUMX, ese es el iterador del que hablaba yo antes, recibe dos parámetros, Ventas, que es la tabla a recorrer y la expresión a evaluar es: Ventas[CantidadETL] * Ventas[Precio].

SUMX

Iteradores en DAX

Los iteradores en DAX, son muy variados en cuanto a su utilidad. Estas funciones especiales tienen una gran importancia y potencia dentro de las expresiones DAX para manejo de modelos tabulares.

  • Hay iteradores de agregación, entre ellos: SUMX, AVERAGEX, MINX, MAXX
  • La función FILTER es un iterador, que recorre la tabla, evalúa la condición y devuelve los registros que la cumplan. De esta función hablaremos más adelante.
  • Otra función muy importante, ADDCOLUMNS es también un iterador, crea una tabla nueva con todas las filas y columnas de la tabla que recorre,  y agrega nuevas columnas, que se llenan a partir de la evaluación de expresiones pasadas como parámetros
  • No pierdas de vista los iteradores en DAX, hay más 🙂

Regresamos a las medidas. De igual forma que antes creamos la medidas para Total Beneficios, con el mismo iterador SUMX y la expresión que corresponde.

Por último, definimos la medida para el Total % Beneficios. En este caso, lo más interesante es que podemos reutilizar las medidas que hemos creado anteriormente, lo que resulta muy cómodo, limpio y efectivo.

        

Resumiendo, las expresiones de las tres medidas creadas son:

Total Importe = SUMX(Ventas;Ventas[CantidadETL]*Ventas[Precio])
Total Beneficios = SUMX(Ventas;Ventas[CantidadETL] * (Ventas[Precio] – Ventas[Coste]))
Total % Beneficios = DIVIDE([Total Beneficios];[Total Importe])

Vamos a comparar entonces, el resultado que se obtiene al trabajar con las medidas

tablaconmedidas

Voy a resumir algunos de los aspectos a tener en cuenta cuando se crea una medida:

  • Se evalúa la expresión para cada una de las filas visibles de la tabla. La visibilidad de las filas, depende del Contexto de filtro existente. Regresaremos a este punto.
  • El iterador garantiza que se cree algo que conoceremos luego como Contexto de fila, que permite al motor conocer el valor exacto de cada una de las filas de cada columna involucrada en la expresión a evaluar
  • No se almacena el resultado, se almacena la expresión DAX como parte del Modelo de datos tabular
  • Las medidas ven y son vistas por todo el modelo, están envueltas por la función CALCULATE, lo que facilita mucho las expresiones que  las utilizan. Sobre este aspecto, que hoy queda sin explicar, regresaré en esta serie. De momento, quedémonos con la diferencia en el comportamiento de las columnas, que si no utilizan funciones de relaciones o navegación, no es posible ven columnas fuera de la tabla actual.
  • Las medidas no se procesan cuando se crean ni cuando se actualizan los datos. las medidas se evalúan y devuelven su resultado, sólo en caso de ser utilizadas directamente en el informe o desde otra medida que esté siendo utilizada en el informe
  • Las medidas son la vía adecuada para casos de ratios o porcientos de contribución al padre, etc.

En esta serie veremos otros ejemplos de las ventajas de trabajar, siempre que sea posible, con Medidas, en lugar de con Columnas Calculadas.

Espero que resulte de utilidad #HappyDAXing !!! 🙂

En la próxima entrada vamos a ver cómo Utilizar variables en medidas DAX en Modelos tabulares con Power BI

4 comentarios en “DAX: Columnas calculadas vs Medidas – II

    1. Ana Bisbé (@ambynet) Autor

      Hola Sergio.
      Es bueno saber que te ha resultado de utilidad.
      Sobre recursos para aprender DAX, hay muchos 🙂 Hace año y medio recopilé esta lista: https://amby.net/2018/01/08/modelos-tabulares-y-dax-recursos/
      Hay algunos enlaces que no están vigentes, tengo que actualizarlos.
      Faltan otros recursos, por ejemplo:
      Mis cursos en LinkedIn Learning
      Power BI esencial: https://www.linkedin.com/learning/power-bi-esencial
      Power BI avanzado: https://www.linkedin.com/learning/power-bi-avanzado
      Excel Business Intelligence 3: Power Pivot y DAX: https://www.linkedin.com/learning/excel-business-intelligence-3-power-pivot-y-dax
      Además:
      https://www.sqlbi.com/training/ – hay dos cursos gratuitos, en inglés, con transcripción en español, el primero está revisado. La traducción del segundo no está contrastada, por herramienta y ya está., por lo que no queda del todo bien.
      Mucho ánimo y #HappyDAXing !!!
      Saludos, Ana

      Me gusta

      Responder
  1. franco

    Hola, tengo la siguiente medida creada:

    VAR = (sum(Sheet1[Posición VN]) – CALCULATE(sum(Sheet1[Posición VN]); DATEADD(Sheet1[Fecha]; -1; DAY)) )

    El problema es que cuando quiere restar la suma de un lunes por ejemplo, como no encuentra el día anterior (ya que la tabla tiene solo días hábiles) me trae infinito.

    Me podrían dar una mano para que reste contra el día anterior que se encuentre disponible?

    Gracias!

    Me gusta

    Responder
    1. Ana Bisbé (@ambynet) Autor

      Hola Franco
      Para el buen desempeño de las funciones de BI de tiempo, es necesario contar con una tabla calendario que va desde el 1 de enero al 31 de dic de cada año que se analice, sin saltos ni repetidos. Esto te debía solucionar el problema. Para crearla hay muchas opciones. Una de ellas, con DAX, por ejemplo:
      MiCalendario = CALENDAR(DATE(1;1;2018);DATE(31;12;2020))
      No olvides relacionar las tablas correctamente en el modelo
      Espero que resulte de utilidad, Saludos

      Me gusta

      Responder

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.