¿Qué son las funciones de tipo tabla?

Son funciones que devuelven una tabla, de ahí el nombre J



Normalmente el uso que solemos darle a las funciones tipo
tabla son en expresiones complejas donde anidamos funciones. Es el uso más habitual,
pero también recordad que podemos utilizarlas para materializar tablas dentro
de nuestro modelo, pero no debemos abusar de ellas ya que engordan nuestro
modelo.



Como ejemplos de funciones tipo tabla destacar las
siguientes 4 las cuales iré realizando distintas entradas donde intentaré
explicarlas para que podáis sacarle el máximo partido:



1- La función FILTER



2- La función ALL



3- La función RELATEDTABLE



4- La función CALCULATETABLE



Estas funciones, no son todas las que existen, pero sí las
que más se suelen usar.



En esta entrada, vamos a ver la función FILTER.





FILTER



 



Lo primero a resaltar de la función FILTER, es que a parte
de ser una función de las denominadas tipo tabla, también pertenece al grupo de
las funciones denominadas Iteradores. Las funciones del iterador enumeran todas
las filas de una tabla determinada y evalúan una expresión dada para cada fila,
es decir, recorren toda la tabla y la evalúan fila a fila en función de los
argumentos de filtro que se le envían.



La expresión de la función FILTER es:



FILTER(<table>,<filter>)



¡OJO! Cómo he comentado en algún momento, la parte
comprendida dentro < > no es la función, sino los argumentos de filtro
que se le envían a la función.



 



Por ejemplo, creamos una tabla calculada que nos devuelva los
productos con ClassName Deluxe. Para ello escribimos la siguiente expresión:

  


Generando esta tabla calculada, estamos generando una nueva
tabla en la que sólo están las filas cuyo resultado devuelto en la columna
ClassName es Deluxe. Este es un caso muy común del uso de la función FILTER,
que es reducir el número de filas mediante las iteraciones.

 



Como podemos ver, el número de filas de la tabla origen
DimProduct es:

 

 

 

Mientras que el número de filas de la nueva tabla Productos
Deluxe es:

 

 

 

Se ha reducido en número de filas considerablemente, pero
repito. No hay que abusar de las tablas ni columnas calculadas. Este ejemplo es
más a modo ilustrativo que práctico.

Vamos a ver otro ejemplo. Tenemos la siguiente métrica:

 


 

Si os fijáis, la función FILTER está anidada con la función
SUMX. Yo quiero computar con el iterador SUMX una suma, pero la tabla que se le
envía no es una tabla física de mi modelo, sino que es una tabla que se calcula
al vuelo en la métrica. ¿Qué tabla es? La que me devuelve la función tipo
FILTER. ¿Qué es lo que hace FILTER? 
Materializa una tabla de la siguiente manera:

El primer argumento, es la tabla que voy a recorrer. En este
caso la tabla de las facturas de las ventas online.

El segundo argumento, es la condición o expresión, con la
que queremos que evalué fila a fila y es que el precio unitario será mayor a
30.



Si mostramos una tabla en el informe con las métricas de
Total Ventas y la métrica recién calculada, obtenemos:

 

 

 

Como se puede apreciar, la columna TotalSales muestra el
total de ventas por marca, y la métrica analizada nos muestra el total de
ventas, sí, pero de los productos que cumplen la condición de precio unitario
superior a 30 €. ¿Se entiende?

Y ahora, viene la pregunta, ¿se pueden especificar más de
una condición como argumento de la función FILTER? La respuesta es sí y hay
varias maneras para realizarla.



Se puede anidar una función FILTER dentro de otra función
FILTER o bien, se puede incluir la función AND. Por ejemplo, a la métrica del
ejemplo anterior, queremos incluirle la condición de filtrado de IDAlmacen =
199. Por lo que con la función AND sería:

 

 

 

O también se puede escribir de la siguiente manera con doble
&&:

 

 

 

En cambio, la otra manera comentada es la anidación de la función
FILTER con otra función FILTER, que sería tal que así:

 


 

Las tres expresiones, producen exactamente el mismo
resultado tal y como podemos ver en la siguiente imagen: 

 

 

 

Entonces, si las 3 expresiones devuelven el mismo resultado,
¿qué diferencia hay entre las 3? Analíticamente ninguna, pero sí puede haberla
a nivel de rendimiento, que puede ser diferente en tablas grandes según el
criterio de filtrado de las condiciones.

Aquí viene otra buena práctica: si una condición es más
selectiva que la otra, aplicar primero la condición más selectiva mediante una
función de FILTER anidada.



¿Qué quiere decir esto? Por ejemplo,
siguiente el ejemplo anterior, si analizamos la tabla FactSalesOnline, el
número de filas cuyo precio unitario es superior a 30 son 8020978 filas de
12627608 tal y como podemos ver en la imagen inferior:

 

 

 

En cambio, el número de filas de la tabla FactSalesOnline en las que el
StoreKey es 199 es de 4645792 de las 12627608.

 

 

 

A la vista de los datos anteriores, la condición más
restrictiva (la que más datos filtra) es la de StoreKey igual a 199 por lo que
la manera de escribir la formula DAX sería la siguiente:

 


 

Como hemos comentado, el resultado de las expresiones es el
mismo pero el rendimiento puede que no sea el mismo. Para ver el efecto, aunque
en este caso no es muy significativo, en un modelo muy complejo y pesado puede
resultar determinante. Sacamos 2 tarjetas en las que mostramos la medida
FilterAnidado y FilterAnidado2 y ejecutamos el analizador de rendimiento.

 

 

 

Iniciamos la grabación, y modificamos el segmentador de mes
en este caso y observamos el resultado:

 


 

El tiempo de ejecución de ambas medidas es prácticamente el
mismo, hay una diferencia de 2 milisegundos para este modelo que es
inapreciable, pero si el modelo fuese mucho más complejo y pesado, la
diferencia puede que aumentase.

 



¡Nos vemos en los datos!