michellepace
Hola.
Recientemente publiqué una pregunta. ¿Debo usar explícitamente «filtro ()» cuando uso CALCULAR? , la respuesta fue sí. A continuación se muestran dos expresiones DAX. El primero devuelve un resultado correcto, el segundo no. Pregunta: ¿Podría alguien explicar por qué la segunda función DAX no funciona como se esperaba? Pensé que, de hecho, estaba aplicando las mejores prácticas al declarar explícitamente FILTER( ).
Cantidad total LY (derecha) = CALCULAR ([Total Quantity], MISMO PERIODO AÑO ( fechas[Date] ))
Cantidad total al año (incorrecto) = CALCULAR ([Total Quantity], FILTRAR (Fechas, MISMO PERIODO AÑO ( fechas[Date] ) ))
Saludos,
michelle
daxer-todopoderoso
En respuesta a michellepace
está bien. Aquí está la explicación completa y definitiva de lo que está pasando. Basta con comprobar lo que esto
FILTER (
Dates,
SAMEPERIODLASTYEAR ( Dates[Date] )
)
lo hace. FILTER es un iterador, por lo que toma lo que está visible actualmente en Fechas y lo revisa fila por fila. ¿Qué hace SAMEPERIODLASTYER? Veamos qué dice dax.guide/sameperiodlastyear/:
Observaciones
El argumento de fechas en SAMEPERIODLASTYEAR puede ser cualquiera de los siguientes:
- Una referencia a una columna de fecha/hora. Solo en este caso se aplica una transición de contexto porque el
la referencia de la columna se sustituye por - CALCULABLE ( DISTINTO (
) )
- CALCULABLE ( DISTINTO (
- Una expresión de tabla que devuelve una sola columna de valores de fecha/hora.
- Una expresión booleana que define una tabla de una sola columna de valores de fecha/hora.
En otras palabras, lo que sucede bajo FILTER es esto:
FILTER (
Dates,
SAMEPERIODLASTYEAR (
// Here is where context transition
// happens...
CALCULATETABLE ( DISTINCT ( Dates[Date] )
)
)
Entonces, ¿qué es lo que ve SAMEPERIODLASTYEAR? Bueno, ve la fecha que pertenece a la fila que se está iterando actualmente. Toma este valor y lo mueve hacia atrás 1 año. Ahora es la parte divertida. Si sucede que la fecha cambiada no está EN BLANCO, la fila se incluirá; si está EN BLANCO (porque se salió del borde del calendario), la fila se filtrará. Por lo tanto, lo que obtiene como resultado depende de la parte de las fechas que vea, pero la semántica del código es la siguiente: de las fechas actualmente visibles, devuelva solo aquellas que no estén en BLANCO cuando se retrasen un año.
Esta es la explicación completa y definitiva de lo que ves.
daxer-todopoderoso
El segundo argumento de FILTER siempre debe ser una condición lógica. Tenga en cuenta que en DAX a veces se lleva a cabo una conversión implícita de expresiones, pero no debe confiar en esto si desea mantener la cordura y no hacer que otros desarrolladores lo maldigan. En su segunda fórmula, está usando SAMEPERIODLASTEAR pero es una función de tabla, no una función lógica. Sin embargo, supongo que DAX convierte esto en VERDADERO cada vez que la función devuelve una tabla no vacía. Por lo tanto, obtienes algo no deseado. Siempre preste atención a los parámetros en las funciones y conozca el tipo de expresiones de datos que devuelven. Tenga cuidado con las conversiones automáticas a menos que sepa con precisión que están ocurriendo y por una buena razón. En cuanto al filtrado en CALCULATE… Todos los argumentos de CALCULATE a partir del segundo deben ser tablas. Y siempre lo son, aunque a veces ves azúcar sintáctico como T[Col] = «valor». Esto, de hecho, es una tabla debajo del capó. Cuando se trata de filtrar, hay una regla de oro en DAX: nunca filtre una tabla cuando puede filtrar una columna. Esto tiene que ver con el funcionamiento y el rendimiento de DAX.
michellepace
En respuesta a daxer-todopoderoso
@Greg_Deckler y @daxer-almighty, gracias a ambos. Voy a ir a través del enlace, así como una explicación. Voy a ir a través de ambos en detalle en la mañana. He estado luchando todo el día. Cuantas más personas como usted respondan a mis preguntas, más me doy cuenta de lo mucho que tengo que aprender. Gracias. ¡Debería haberme subido a este barco hace 10 años! 🙂
daxer-todopoderoso
En respuesta a michellepace
está bien. Aquí está la explicación completa y definitiva de lo que está pasando. Basta con comprobar lo que esto
FILTER (
Dates,
SAMEPERIODLASTYEAR ( Dates[Date] )
)
lo hace. FILTER es un iterador, por lo que toma lo que está visible actualmente en Fechas y lo revisa fila por fila. ¿Qué hace SAMEPERIODLASTYER? Veamos qué dice dax.guide/sameperiodlastyear/:
Observaciones
El argumento de fechas en SAMEPERIODLASTYEAR puede ser cualquiera de los siguientes:
- Una referencia a una columna de fecha/hora. Solo en este caso se aplica una transición de contexto porque el
la referencia de la columna se sustituye por - CALCULABLE ( DISTINTO (
) )
- CALCULABLE ( DISTINTO (
- Una expresión de tabla que devuelve una sola columna de valores de fecha/hora.
- Una expresión booleana que define una tabla de una sola columna de valores de fecha/hora.
En otras palabras, lo que sucede bajo FILTRO es esto:
FILTER (
Dates,
SAMEPERIODLASTYEAR (
// Here is where context transition
// happens...
CALCULATETABLE ( DISTINCT ( Dates[Date] )
)
)
Entonces, ¿qué es lo que ve SAMEPERIODLASTYEAR? Bueno, ve la fecha que pertenece a la fila que se está iterando actualmente. Toma este valor y lo mueve hacia atrás 1 año. Ahora es la parte divertida. Si sucede que la fecha cambiada no está EN BLANCO, la fila se incluirá; si está EN BLANCO (porque se salió del borde del calendario), la fila se filtrará. Por lo tanto, lo que obtiene como resultado depende de la parte de las fechas que vea, pero la semántica del código es la siguiente: de las fechas actualmente visibles, devuelva solo aquellas que no estén en BLANCO cuando se retrasen un año.
Esta es la explicación completa y definitiva de lo que ves.
michellepace
En respuesta a daxer-todopoderoso
Hola @daxer-almighty Gracias, esa es una excelente explicación. Ahora lo entiendo 🙂
greg_deckler
@michellepace: no estoy seguro de quién le dio el consejo de que siempre debe usar FILTRO explícitamente en un CÁLCULO, pero ese es un mal consejo. No lo hace y en realidad hay una guía de que debe evitar hacerlo.
https://docs.microsoft.com/en-us/power-bi/guidance/dax-avoid-avoid-filter-as-filter-argument
Pero, de nuevo, tiendo a evitar usar CALCULAR.
CNENFRNL
Noté que escribiste fórmulas de esta manera en tus dos publicaciones,
FILTER( tbl, filtering_exp )
Infiero que asumes el todo intacto problema es filtrado por filtrado_exp (corrígeme si mi conjetura es incorrecta); de hecho, no es el caso. Está muy claro que el contexto de la evaluación es importante en cualquier momento y lugar en DAX. No hay excepción a FILTER() también; tbl ya pasó por el filtrado de contexto inicial antes de ingresar a FILTER.
Jeffrey wang, uno de los padres fundadores del motor VertiPaq, reveló algunos detalles de la forma en que funcionan los contextos de filtro,
http://mdxdax.blogspot.com/2011/03/logic-behind-magic-of-dax-cross-table.html
Aunque se escribió en 2011, hace casi una década, ¡funciona como la brújula más precisa para navegar a través de DAX!
antrikshsharma
@michellepace SAMPERIODLASTYEAR es una función de tabla y la está utilizando en el segundo argumento de FILTER donde se evalúan las condiciones booleanas para devolver la lista de valores del primer argumento de FILTER que satisfacen los criterios especificados en el segundo argumento.
Tanto FILTER como SAMPERIODLASTYEAR están haciendo su trabajo y ambos están siendo evaluados en el contexto del filtro, ¿cómo verificar que SPLY se evalúe en el contexto del filtro? SAMPERIODLAS AÑO ( Fechas[Date] ) es equivalente a decir SAMPERIODLAS AÑO ( VALORES ( Fechas[Date] ) )
Pero la presencia de SPLY no tiene impacto en la parte FILTER (Fechas), y está obteniendo un resultado similar al año actual.
Digamos que el contexto del filtro es 2020. Consulte los comentarios en la imagen a continuación:
Pero cuando usa solo SAMPERIODLASTYEAR, toma las fechas actuales y retrocede un año y obtiene las fechas de 2019 y las aplica al contexto del filtro y, por lo tanto, obtiene el resultado correcto.