¡Jueves de post! Después de abordar el tema ganador en la encuesta que lancé en LinkedIn, ahora toca abordar el segundo tema: Iteradores.

Los iteradores, desde mi punto de vista, son unas funciones que nos aportan un juego y una capacidad de cálculo a nuestro modelo increíble y lo voy a intentar mostrar a lo largo una serie de post.

Antes de comenzar con los iteradores, y por contextualizar un poco, voy hacer una breve introducción a las funciones conocidas como Agregaciones. ¿Qué son las funciones de agregación? Son funciones que computan o agregan los valores de una columna dentro de una tabla y devuelven un único valor. Las funciones de agregación pueden ser de diferentes formas:

  1. Funciones Aditivas: por ejemplo, las ventas totales este mes.
  2. Funciones Semi-aditivas: por ejemplo, clientes con ventas este mes.
  3. Funciones No Aditivas: última venta de un producto.

Una pregunta, ¿por qué esta última es no aditiva? Por qué no puedo agregar nada como tal ya que la última venta de un producto es un único valor que no voy a obtener sumando, por ejemplo.

 

Funciones aditivas:

A continuación, os muestro algunas de funciones aditivas:

  • SUM
  • AVERAGE
  • MIN
  • MAX
  • COUNT
  • COUNTBLANK

Por ver algún ejemplo de qué podríamos utilizar o hacer uso de la función SUM:

  • Sobre la cantidad
  • Importe de venta
  • Coste de la venta

 ¿Y cómo funciona? Pues vamos a verlo con un ejemplillo muy sencillo:

 

 
 

En la medida anterior, le pasamos el atributo a la función (SalesAmount) y la computo devolviendo un único valor.

 

Funciones semi-aditivas

Con las funciones semi-aditivas seguimos pudiendo utilizar SUM para agregar ciertas dimensiones, pero no todas. Puede haber determinados cálculos que sí que agregue pero que no tenga sentido hacer el cálculo por igual. Por ejemplo: Stock de productos en almacen

  • El stock total de los artículos es la suma de todos stocks de los artículos.
  • El stock del año, NO es la suma de los stocks mensuales, sino el stock al final de año.
  
¡¡ATENCIÖN SPOILER!! 
 
Por ejemplo, para el segundo caso, podemos usar la función ENDOFYEAR() que devuelve la última fecha del año del contexto actual para la columna de fechas especificada. (lo veremos en la serie dedicada a todo lo relacionado con fechas)

 
 

Nota: Apuntar que esta es una función de inteligencia de tiempos. Las funciones de inteligencia de tiempo necesitan que tengamos una tabla de fechas marcada como tal en el modelo sino es posible que no funcionen o el funcionamiento no sea el deseado.

Y como segundo argumento le enviamos el fin de año que queramos especificar, pero si os fijáis la función por sí misma no bastaría. ¿Dentro de qué otra función estamos haciendo uso es ENDOFYEAR para calcular el fin de año?... Del CALCULATE. Acordaros CALCULATE es ese tipo de función que nos permite hacer ese cálculo especial. Por eso suelo insistir en que CALCULATE seguramente sea la función que más utilicéis en vuestros modelos.

 FIN SPOILER

 

Funciones no aditivas

 

Agregaciones no aditivas, por ejemplo DISTINCTCOUNT(). Tengo un único valor y hay que tener en cuenta cuando aplicarlo. No todos los agregados o los conteos o valores que podamos mostrar son la suma de todas las partes. Me explico:

  • ¿A cuántos proveedores he comprado en el mes de Julio? à 100
  • ¿A cuántos proveedores he comprado en el mes de Agosto? à 250
  • ¿A cuántos proveedores he comprado en Julio y Agosto?

No necesariamente tiene que ser 350 porque puede haber proveedores a los que hemos comprado en ambos meses.

 En definitiva. todas las funciones de agregación que he descrito hasta ahora funcionan en columnas y devuelven un único valor. Por lo tanto, agregan valores de una sola columna solamente.

Bien, una vez ya contextualizadas las funciones de agregación, vamos a ver los iteradores, que no dejan de ser funciones de agregación pero que, en lugar de una única columna como argumento, pueden agregar una expresión.

Los iteradores siempre aceptan al menos dos parámetros: el primero es la tabla que quiero evaluar; el segundo suele ser una expresión que se evalúa para cada fila de la tabla.

¿Y cuales son las funciones de iteración? A continuación, unas de ellas:

  • SUMX
  • AVERAGEX
  • MINX
  • MAXX
  • COUNTX

Visto las funciones de agregación de arriba, ¿se podría decir que todos los iteradores terminan en X? Pues la respuesta es NO, acordaros por ejemplo de la función FILTER (os dejo el link aquí)

¿Y cómo funciona un iterador? Supongamos que tenemos la siguiente tabla y necesitamos obtener el importe total vendido. ¿Cómo lo haríais?

 
 La primera respuesta que viene a la cabeza es con una columna calculada que multiplique “Precio Unitario” y “Cantidad Vendida”, ¿no?

 

Es un camino completamente plausible y que podríamos optar, pero no es la práctica recomendada ya que como he comentado en alguna ocasión y el motivo es:

Las tablas y columnas calculadas se calculan en tiempo de actualización. Es decir, se van a materializar al final del procesamiento. Hasta que no dispongamos de todo el modelo cargado, estas no se van a cargar. Esto es uno de los motivos por lo que no es recomendable abusar de este tipo de datos. Además, tienen peor ratio de compresión por lo que hacen que nuestro modelo engorde y ocupe más espacio.

 ¿Y cómo calculamos el importe de las ventas Javi? Pues con las funciones que dan el título a este post:

 
 

Arrastramos la medida a la matriz y cómo podemos observar ahora tenemos el Importe Total por cada producto. ¿Y cómo lo hace?

 

 

Cómo primer argumento, le estamos pasando la tabla de Ventas y como segundo argumento la expresión que es la cantidad vendida por el precio unitario y el iterador lo que hace es recorrer la tabla entera fila a fila evaluando la expresión de la siguiente manera:

Para la primera fila, que es el producto “Pan”, multiplica la cantidad vendida y el precio unitario:

 
 
 Y como resultado nos devuelve el valor 1000 € pero NO lo materializa como lo haría una columna calculada, sino que es calculado al vuelo. Y así sucesivamente hasta el final de la tabla.¿Se entiende?
 
Por ahora suficiente, en el siguiente post abordaremos los iteradores y los contextos... ¡Nos os lo perdáis!

¡Nos vemos en los datos!