Contenidos
Iba a titular este blog «MEDIANX y las funciones X», pero sonaba demasiado a una banda de la década de 2030, así que opté por MEDIANX devuelve en blanco en DAX. Pero el artículo cubre más que solo MEDIANX y el “problema” en blanco. Pero primero algunos antecedentes.
Ayudé a un cliente con un problema extraño esta semana: una medida devolvía EN BLANCO cuando, intuitivamente, debería haber devuelto algún valor. Había muchas partes móviles en el problema real y en cómo lo resolví, y no entraré en todos esos detalles. Sin embargo, lo que haré es usar mi experiencia y lo que aprendí esta semana para compartir algunas ideas para usted en este artículo:
- Que hace una función X
- Cómo construir y usar tablas de prueba en DAX
- MEDIANX, vs AVERAGEX
- La forma indulgente en que DAX evalúa la definición de BLANK
Si sus ojos no están vidriosos a estas alturas, siga leyendo.
Qué hace una función X
Una función X es una clase de funciones en DAX que también se conocen como «iteradores» (tenga en cuenta que también hay otras funciones iterativas, como FILTRO, pero aquí solo me refiero a las funciones X). Es un gran tema por sí solo, y este artículo no será la guía definitiva para las funciones X. Pero te daré un par de ideas.
He aprendido mucho sobre cómo enseñar DAX a la gente durante los últimos 6 años, y mis métodos de enseñanza han evolucionado durante ese tiempo. Recuerdo haber hablado con cariño en el Microsoft Data Insights Summit con Will Thompson sobre el tema «DAX 50 – DAX para el resto de nosotros». Will me dijo “no menciones la palabra ‘iterador’ ya que es demasiado confusa”. No estaba de acuerdo con Will en ese momento, pero su comentario se me quedó grabado. Con el tiempo, he cambiado la forma en que enseño DAX. En estos días, le muestro a la gente cómo agregar una columna calculada en una tabla (todos pueden hacerlo, es muy fácil). Luego explico que una función X hace exactamente lo mismo, es solo que no puedes ver los resultados intermedios materializados frente a sus ojos.
Veamos un ejemplo para mayor claridad.
Ejemplo
Estoy usando mi esquema de estrella simple estándar de Adventure Works para este ejemplo.
Digamos que quiero escribir una medida que devuelva la cantidad mediana gastada en todos los clientes. El problema es que no tengo las ventas totales de cada cliente en mi modelo de datos. Tengo una tabla de clientes y una tabla de ventas, pero en ninguna parte están las ventas totales de cada cliente.
Ahora, podría calcular la mediana de las ventas de todos los clientes calculando primero las ventas totales de cada cliente en una columna calculada en la tabla de clientes y luego agregar una imagen a mi informe para calcular la mediana como se muestra a continuación.
Medida: Ventas totales = SUM (Ventas[ExtendedAmount])
Creé una columna calculada en la tabla de clientes: Ventas personalizadas = [Total Sales]
Como puede ver arriba, ahora puedo ver las ventas totales de cada cliente.
Luego, todo lo que tenía que hacer era agregar una imagen al lienzo del informe (1 a continuación), agregar la columna calculada (2) y establecer la agregación en MEDIANA (3).
Como puede ver en la imagen de arriba, la respuesta es 270.27. El problema con este enfoque es que tuve que escribir una columna calculada para obtener la respuesta. Si bien hay un tiempo y un lugar para una columna calculada, no es necesario crear una columna calculada para obtener esta respuesta. El punto que estoy tratando de hacer es que la columna calculada arriba es conceptualmente fácil de entender para cualquiera. Es fácil de escribir, puede resolver el problema paso a paso, puede ver los resultados provisionales y cualquier persona con experiencia en Excel puede hacerlo con muy poca comprensión de DAX. Comprender la función MEDIANX es mucho más difícil; más difícil hasta que se dé cuenta de que MEDIANX está haciendo EXACTAMENTE lo mismo que esta columna calculada.
Aquí está la fórmula MEDIANX.
Medida mediana de ventas de clientes = MEDIANAX(Clientes,[Total Sales])
En la fórmula anterior
- La X (azul) es el indicador de que se trata de una función X. Esta es la pista de que esta es una de las funciones que se comporta como una columna calculada.
- La tabla (verde) es la tabla en la que habría escrito su columna calculada si lo estuviera haciendo de esa manera.
- La medida (naranja) es la fórmula dentro de la columna calculada que habría escrito si lo hubiera hecho de esa manera.
- El MEDIANO (rojo) es lo que sucede con los números al final.
Aquí está la lección: Una función X es exactamente lo mismo que una columna calculada. Las únicas diferencias son que 1) no puedes VER lo que está sucediendo y 2) no almacena permanentemente la fila por resultados en ninguna parte. Pero el proceso de hacer el cálculo es idéntico.
Ahora, la verdad es que están sucediendo muchas cosas bajo el capó para obtener este resultado. Hay una función CALCULATE implícita oculta, hay un contexto de fila y una transición de contexto, pero el punto es que no es esencial que comprenda todas estas cosas técnicas para poder aprender un poco más sobre cómo usar y comprender DAX. La forma en que enseño DAX en estos días es para mostrarle a la gente cómo hacer una columna calculada, luego mostrarle a la gente que se puede hacer lo mismo (en este caso) usando una medida y una función X. La moraleja aquí es, si está tratando de escribir una medida, se queda atascado y sabe cómo hacerlo como una columna calculada, luego primero cree la columna, luego averigüe cómo migrarla a una medida desde allí usando el principio que he demostrado.
Cómo crear y usar tablas de prueba en DAX
Ahora volvamos al problema del cliente: ¿por qué MEDIANX devolvió un espacio en blanco? Se me ocurrió que la forma más fácil de visualizar lo que estaba sucediendo era construir una tabla de valores de tiempo de ejecución usando los operadores de llaves {}. Aprendí lo útil que es esta técnica cuando veo demostraciones y publicaciones de dos personas realmente inteligentes de DAX (Phil Seamark y Owen Auger).
Medida de prueba = MEDIANAX({1,2,3,6,9},[Value])
La forma en que funciona esta medida es que el bit entre paréntesis (verde) genera una tabla de tiempo de ejecución. La parte naranja [Value] me permite acceder a los valores en la única columna de la tabla que acabo de crear. Los bits rojo y azul son los mismos que antes.
La función anterior devolvió 3
Entonces decidí probar AVERAGEX
Para el registro, AVERAGEX devolverá el valor medio (total dividido por el recuento) mientras que MEDIANX devolverá el valor medio. En el caso de que haya un empate para el valor medio (es decir, un número par de valores), es la media de los 2 valores medios.
Luego escribí la siguiente medida de prueba.
Luego esto
Y luego el centavo cayó para mí. ¿Qué pasaría si escribiera esto?
Estas medidas de prueba realmente me ayudaron a comprender lo que estaba sucediendo bajo el capó, y espero que también te haya ayudado.
El lenguaje DAX es muy indulgente.
DAX es un lenguaje muy indulgente. En muchos (la mayoría) de los otros lenguajes, un espacio en blanco o un nulo no se evalúan con el mismo resultado que 0. En el lenguaje DAX, un espacio en blanco o un nulo se evaluarán como 0 a menos que le indique explícitamente que no lo haga, utilizando el nuevo == (doble signo igual). Dicho de otra manera, 0 = EN BLANCO () es VERDADERO, mientras que 0 == EN BLANCO () es falso. Llamo al doble signo igual «realmente igual», pero el nombre oficial es «estrictamente igual a».
Medida de prueba = MEDIANX ({EN BLANCO (), EN BLANCO (), EN BLANCO (), 6,9},[Value])
Con eso en mente, la medida de prueba que se repitió anteriormente es evaluar los espacios en blanco como si fueran numéricamente 0 al hacer la evaluación de la mediana y, finalmente, devolver el BLANK nativo () al final. Por supuesto, la diferencia entre el promedio y la mediana es que la mediana devuelve el número del punto medio. En este caso, el punto medio es un espacio en blanco y, por lo tanto, este es el resultado que se devolvió.
Ahora, si no desea que los espacios en blanco se traten como 0, tendría que filtrarlos antes de calcular la mediana.
Ignorando BLANKS () en un MEDIANX
Esto resultó ser un poco más complicado de lo que pensé. Primero necesitaba una nueva muestra para probar. Creé otra columna calculada, esta vez en la tabla Productos. Sabía por experiencia previa que no todos los productos tienen ventas, por lo que esto devolvería algunos espacios en blanco. Vea abajo.
Cuando agregué esta columna como una tarjeta a mi informe y configuré la agregación en MEDIANA, esto es lo que obtuve.
Cuando escribí la medida de prueba equivalente usando MEDIANX, esto es lo que obtuve
Así que tengo que decir que me sorprendió mucho que mi columna calculada y mi medida me dieran un resultado diferente. Después de un poco de más pruebas e investigación, resulta que cuando usa una columna en una tarjeta en Power BI y encuentra el valor mediano, el objeto visual filtra automáticamente los ESPACIOS EN BLANCO, lo quiera o no. No pude ver ninguna forma de cambiar este comportamiento.
Parte 2 la próxima semana
Resolver el problema de MEDIANX como medida es un poco más difícil que con una columna. El problema es que la columna en realidad no existe cuando la escribe como medida, pero aún debe filtrar los espacios en blanco antes de hacer el cálculo. Podrías intentar escribir una medida como esta …
Medida de prueba 1 = MEDIANX (Productos, si ([Total Sales]= 0, EN BLANCO (),[Total Sales]))
pero terminará con el mismo resultado, porque uno de los resultados de la instrucción IF simplemente agrega el BLANK () nuevamente.
Escribir una medida para esto es un gran tema en sí mismo, y explicaré cómo puede usar DAX Studio (paso a paso) para resolver tal problema en mi próximo artículo la próxima semana.