Y otra vez es lunes y los lunes son… ¡lunes de post! Como muchos de vosotros sabéis, el domingo pasado lancé una encuesta a través de mi perfil de LinkedIn preguntando el tema del que os gustaría que hablase, pues bien, el resultado de la votación ha sido el siguiente:
El tema ganador ha sido Relaciones en Power BI, así que lo
prometido es deuda, y este es el primer post de la serie Relaciones en Power
BI.
Lo primero, antes de seguir, ¿sabemos cuál es la finalidad de una relación en un modelo de datos? Citando la web de Microsoft:
Una relación de modelo propaga los filtros aplicados en la columna de una tabla de modelo a otra tabla del modelo. Los filtros se propagarán siempre que haya una ruta de relación que seguir, lo que puede implicar la propagación a varias tablas.
Las rutas de relación son deterministas; es decir, los filtros siempre se propagan de la misma manera y sin variación aleatoria. Sin embargo, las relaciones pueden deshabilitarse o el contexto del filtro puede modificarse debido a los cálculos del modelo que usan funciones DAX concretas.
Resumiendo, la finalidad de una relación entre tablas es la propagación de los filtros aplicados. ¿Entendido? Ahora, las relaciones en Power BI pueden ser físicas o virtuales. (Como en la vida misma ¿eh?) Bien, bromas a aparte, dentro de estos dos bloques, las relaciones físicas puedes ser activas o inactivas (otra vez, como en la vida misma J ) Y ahora os estaréis preguntando, ¿Cuáles son las relaciones inactivas? Las relaciones inactivas son las relaciones (dos o más) que existe entre dos tablas, pero como sabemos sólo puede estar una activa.
La línea continua es la relación activa y va a ser la relación por la que se propagará el filtro “siempre”. Y ahora diréis, ¿y por qué siempre lo has colocado entre “ “? Pues porque salvo que le indiquemos lo contrario, Power BI va a optar siempre por ese camino. ¿Y cómo le digo a Power BI que use la relación inactiva? Pues con la función DAX USERELATIONSHIP. Vamos con la definición como siempre primero de la web de Microsoft:
La función USERELATIONSHIP especifica la relación que se va a usar en un cálculo concreto como la que existe entre columnName1 y columnName2
Donde:
ColumnName1: Nombre de una columna existente, con la sintaxis DAX estándar y completo, que normalmente representa el lado "varios" de la relación que se va a usar. Si los argumentos se proporcionan en orden inverso, la función los intercambia antes de usarlos. Este argumento no puede ser una expresión.
ColumnName2: Nombre de una columna existente, con la sintaxis DAX estándar y completo, que normalmente representa el lado "uno" o de búsqueda de la relación que se va a usar. Si los argumentos se proporcionan en orden inverso, la función los intercambia antes de usarlos. Este argumento no puede ser una expresión.
Ahora bien, una vez visto la definición de la misma, os preguntaréis ¿y qué finalidad tiene esta función? Pues es una función muy útil y que en mi día a día la uso a diario, sobre todo para hacer comparativas entre fechas de planificación y fechas realizadas, para saber el cumplimiento. También es muy útil para poder analizar pedidos, con fechas de recepción, fechas de envío, fechas de entrega…
Ahora que ya te he convencido de que es una función muy recurrente, vamos a ver cómo usarla. Vamos a nuestro modelo de datos de Power BI de Contoso y vamos a calcular el total de ventas, para ello escribimos y arrastramos la medida a la matriz donde tenemos los distintos países:
Y obtenemos:
Como hemos comentado, la relación por la que está calculando Power BI la medida TotatVentas es por la relación activa, que en este caso es DateKey a FechaPedido:
Pero en vez de querer calcular la medida por la relación activa queremos calcularla por la inactiva que es FechaEnvio. Para ello, vamos a usar la función USERELATIONSHIP y escribimos:
Uy… nos devuelve un error. ¿Por qué puede ser? … Pues por algo que no os he comentado y es que USERELATIONSHIP es un modificador de la función CALCULATE. CALCULATE puede activar una relación durante la evaluación de su expresión usando este modificador. Por lo que si reescribimos la función tal que así:
Y la arrastramos a la matriz que tenemos en el informe:
Vemos que los valores para tanto los países como para el total no es el mismo y eso se debe a que la relación que estamos usando en esta medida es FechaEnvio.
Y ahora, viene la vuelta de tuerca, en el contexto del informe, está filtrado el año 2009, pero… ¿qué pasaría si yo a la función CALCULATE le paso como argumento de filtro que el año de los pedidos ha de ser 2009 y eso se lo añado a USERELATIONSHIP? Vamos a verlo:
Y esta medida nos devuelve:
Como podemos ver, nos devuelve otros valores completamente distintos que vienen a ser todas las ventas con fechapedido igual a 2009 y filtradas por fechaEnvio al usar la función USERELATIONSHIP.
¿Y por qué está ocurriendo esto? Porque Cuando usa USERELATIONSHIP en una instrucción CALCULATE, todos los argumentos de filtro se evalúan utilizando los modificadores de relación que aparecen en la misma instrucción CALCULATE independientemente del orden en el que lo hayamos escrito.
Algo importante que no he comentado a propósito ya que estaba esperando al final, es que USERELATIONSHIP no introduce ningún filtro por sí mismo. ¿Qué quiere decir? Que la función lo único que hace es indicar a Power BI el camino a seguir para propagar la dirección de filtrado con los filtros que apliquemos, sólo cambia la forma en que se aplican otros filtros al modelo. ¿Entendido?
En definitiva, USERELATIONSHIP es una función muy sencilla de aplicar pero que nos permite realizar diferentes análisis en función de las relaciones que tengamos en nuestro modelo.
¡Nos vemos en los datos!
