Aquí estoy de nuevo con la saga de post relativos a los
iteradores. Esta vez os voy hablar de los contextos anidados con iteradores.
En el post de contexto fila y filtro (que si no lo habéis
leído os dejo aquí el link) y el de la semana pasada que fue el primero de la
saga de iteradores, vimos que DAX crea un contexto de fila cada vez que ejecuta
una iteración o creamos una columna calculada.
Esta vez, voy a cambiar un poco la dinámica del post, ya que
hemos visto la “teoría” de los iteradores y vamos directamente con la práctica,
que es como mejor se aprende. Para ello nos vamos a nuestro modelo de Contoso
de Power BI y vamos a crear una columna calculada en nuestra tabla de dimensión
DimProduct en la que nos muestre un ranking de los productos más caros a los más económicos.
Para ello, escribimos la siguiente métrica:
Nota: La función EARLIER, según la web de Microsoft, devuelve
el valor actual de la columna especificada en un paso de evaluación externo de
la columna mencionada.
EARLIER es útil para
los cálculos anidados en los que se quiere usar un determinado valor como
entrada y generar cálculos basados en esa entrada. En Microsoft Excel, estos
cálculos solo se pueden realizar dentro del contexto de la fila actual. Sin
embargo, en DAX puede almacenar el valor de la entrada y luego hacer cálculos
con los datos de toda la tabla.
EARLIER se usa
principalmente en el contexto de columnas calculadas y su sintaxis es:
Column es la columna o expresión que se resuelve en una columna
Number es un número positivo para el paso de evaluación externo.
El siguiente nivel de evaluación externo se representa mediante 1; dos niveles
externos se representan mediante 2, y así sucesivamente.
Si se omite, el valor predeterminado es 1.
Bien, volviendo a la métrica creada, esta nos ha creado la
siguiente columna con el ranking correspondiente como podéis ver:
Ahora os lanzo una pregunta, ¿Cuántos contextos tenemos en
la expresión? ¿Y de qué tipo son esos contextos? ¿1? ¿2? ¿5?
….
Como hemos visto, si yo creo una columna
calculada, esta crea un contexto de fila ¿Hasta aquí se entiende? Bien, y si
dentro de esa columna calculada hago uso de un iterador que también me crea un
contexto de fila, ¿Cuántos contextos tengo? … La respuesta es 2. Tengo el
contexto de fila que me ha generado la columna calculada y el contexto de fila
que me ha generado el iterador. ¿Correcto?
Volviendo un poco a la función EARLIER, es una función
especial que me permite acceder al valor de una columna en un contexto anterior
al que me encuentro. Sabiendo esto, y que en la medida anterior hay dos
contextos, ¿sabemos indicar cuál es el contexto más externo y el contexto más
interno? Dicho de otra forma, de los dos contextos presentes, ¿cuál es el
primero en aparecer? ¿El de la columna o el iterador? Cortocircuito mental ¿eh? :)
Y ahora entra en
juego la función EARLIER, que me permite obtener el valor del precio en el
contexto de fuera en el que me encuentro que es el de la columna calculada:
¿Se entiende? Vamos a detallarlo un poco más, para ello
ordenamos la tabla por el ranking de manera ascendente de tal forma que nos
situemos en la fila número 1.
¿Cuál es el precio unitario para la primera fila? El valor
es 3199.99 €. Y cuándo se ejecute el iterador, ¿cuál va a ser el valor del
precio unitario? Depende, estamos recorriendo la tabla de productos por lo que
irá variando por cada fila en la que pasa, desde la primera hasta última.
Es decir, lo que debo hacer es comparar el valor en el que
estoy (3199.99€), que es el de la fila en el que estoy creando la columna
calculada con el resto de valores.
Entonces, cuando estoy en el segundo iterador el valor del
precio unitario va a equivaler a la fila que estoy recorriendo y me lo está
comparando con el valor anterior. ¿Se entiende?
Lo que viene a ser lo mismo, si quiero comparar el valor de
las filas que estoy recorriendo con el iterador con el valor de la fila en la
que me encuentro en la columna calculada que es el contexto de fila 1, es
cuando interviene EARLIER que me permite obtener ese valor, es decir, el valor
del precio unitario en el que estoy.
Vamos a la expresión para analizarlo de otra forma:
En la medida anterior, tenemos una sintaxis muy similar a la
vista hasta ahora con la diferencia de que no tenemos la función EARLIER y
estamos creando una variable para quedarme con el valor de la fila en la que
estoy iterando por la columna calculada. Me explico:
Se
ejecuta la medida, lo primero que hacemos es entrar en la fila calculada y almacenamos
ese valor en el variable PrecioUnitario del contexto de fila en el que me
encuentro. (3199.99€):
Y ahora lo que realiza es el contaje de las filas de la
tabla DimProduct que la engloba la función FILTER:
Recorremos todas las filas, y comparamos el precio de todas
las filas con el valor almacenado en la variable PrecioUnitario (3199.99 €),
que es el valor de la fila en la que me encuentro de la columna calculada, y así sucesivamente hasta la última fila de la tabla.
Y con esto, es suficiente por hoy. Espero que haberme explicado y que os sea útil.
¡Nos vemos en los datos!