¿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!