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.
dimensión DimDate a la tabla de hechos FactSales, tenemos dos relaciones una
con una línea continua y otra con una línea discontinua.
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!