jhowe1
*** volver a publicar como parece haber sido bloqueado cuando agregué la medida de la palabra al título / tema en la publicación original, agregué totales para mostrar los resultados esperados para el recuento del grupo ***
Hola a todos,
Estoy luchando para escribir / calcular esta medida en DAX. La definición de tasa de recuperación es el recuento de reservas de servicio repetidas (recuento de número de reserva distinto, debe ser distinto de todos modos, pero por si acaso) para un cliente, combinación de activos dentro de una semana (Cerrado el día, período de 7 días). Entonces salgo a reparar una máquina, si me llaman nuevamente para reparar la misma máquina para el cliente dentro de una semana, entonces es un retiro de 1 (o más si me llaman varias veces dentro de una semana). He resaltado los grupos en diferentes colores. ¡Gracias! EDITAR: Lo siento, me di cuenta de que sería más útil si publiqué el código SQL para generar datos, consulte a continuación:
SELECT FB.BookingNumber, FB.EngineerEmployeeID, FWO.ServiceAccountRecID AS Customer, FWO.AssetRecID AS Asset, FWO.ClosedOn FROM dbo.FactWorkOrder AS FWO
JOIN dbo.FactBooking AS FB ON FB.WorkOrderID = FWO.WorkOrderID WHERE FWO.WorkOrderType="Breakdown" AND AssetRecID IS NOT NULL AND ClosedOn IS NOT NULL ORDER BY BookingNumber
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1,
Creo que gran parte del problema se debe a la forma en que se relacionan los datos, para mí la reserva es el hecho, dadas las relaciones, así que agregué el activo y cerré las claves a la tabla de reservas, luego creé una columna de cálculo que identifica si la reserva es un retiro
Recall Rate Flag =
VAR _closed_on = Booking[Closed_on]
VAR _closed_minus_7 = DATE(YEAR(Booking[Closed_on]), MONTH ( Booking[Closed_on] ), DAY (Booking[Closed_on])) - 7
VAR _customer = ( Booking[KEY_Customer] )
VAR _asset = ( Booking[KEY_Asset] )
VAR _engineer = ( Booking[KEY_Engineer] )
VAR _booking = ( Booking[KEY_WorkOrder] )
RETURN
if(CALCULATE (
COUNTROWS ( Booking ),
FILTER(
ALL( Booking ),
_asset <> -1
&& Booking[Closed_On] < _closed_on
&& Booking[Closed_On] >= _closed_minus_7
&& Booking[KEY_Asset] = _asset
&& Booking[KEY_Customer] = _customer
&& Booking[KEY_Engineer] = _engineer
)
)>0, 1)
Luego creó una medida que cuenta las reservas que son retiradas
Recall Rate New = sum('Booking'[Recall Rate Flag])
que da como resultado la imagen a continuación, es posible que deba limpiar un poco los datos al ingresar para asegurarse de tener uno a uno en la orden de trabajo y la reserva.
Puedo adjuntar el archivo aquí o enviárselo a través de mensaje privado, su elección.
Gracias
v-lionel-msft
Hola @ jhowe1,
Primero, obtiene la tabla anterior a través de una consulta SQL y luego calcula la ‘tasa de recuperación’ de la tabla anterior, pero tengo algunas dudas sobre la lógica de cálculo de la ‘tasa de recuperación’.
1. ¿Qué significa el valor nulo de cada grupo en ‘tasa de recuperación’?
2. ¿Es la acumulación de grupo de ‘tasa de recuperación’?
Dé un ejemplo para ilustrar la lógica de cálculo de la «tasa de recuperación».
¿O es esto lo que quieres?
Atentamente,
Lionel Chen
Si esta publicación ayuda, entonces por favor considere Acéptalo como la solución para ayudar a los demás miembros a encontrarlo más rápidamente.
jhowe1
En respuesta a v-lionel-msft
Hola gracias por tu respuesta es muy apreciado. Como dije claramente en la publicación, deseo contar las combinaciones de clientes y activos dentro de un período de 7 días. Una recuperación se cuenta DESPUÉS de la primera aparición, de ahí el espacio en blanco en la primera fila de los grupos. Creo que necesito algo como esto, sin embargo, no he usado SUMMARIZECOLUMNS antes y no puedo obtener la sintaxis correcta, sigo recibiendo errores ‘la expresión se refiere a múltiples columnas. varias columnas no se pueden convertir a un valor escalar. Querré mostrar el recuento de clientes, combinaciones de activos dentro de un período de 7 días, PER Engineer de forma visual. (El ingeniero no es importante en el cálculo, solo quiero poder dividir por ingeniero en una imagen).
Recall Rate =
SUMMARIZECOLUMNS(
WorkOrder[KEY_Customer],
WorkOrder[KEY_Asset],
Booking[KEY_Engineer],
FILTER(WorkOrder, DATESINPERIOD('Date'[Date],LASTDATE(WorkOrder[Closed On]), -7, DAY))) - 1
jhowe1
¿Puedo obtener ayuda con esto, por favor? Comenzará a ser urgente gracias.
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1,
Eche un vistazo a la siguiente medida, muy similar a la respuesta de @ v-lionel-msft pero tiene en cuenta la ventana de 7 días, tenga en cuenta que la medida se evaluará en el contexto de los datos que se muestran en la visualización y los filtros. aplicado y solo contará las retiradas en la ventana representada por el contect. y los 7 días anteriores, por lo que si un artículo se repara una vez cada 8 días, no se contará como un retiro del mercado.
Espero que tenga sentido
Recall Rate =
var _closed_on = SELECTEDVALUE('Table'[ClosedOn])
var _closed_minus_7 = DATE(YEAR(SELECTEDVALUE('Table'[ClosedOn])), MONTH(SELECTEDVALUE('Table'[ClosedOn])), DAY(SELECTEDVALUE('Table'[ClosedOn]))) - 7
var _customer = SELECTEDVALUE('Table'[Customer])
var _asset = SELECTEDVALUE('Table'[Asset])
return
CALCULATE(
COUNTROWS('Table'),
FILTER(
ALL('Table'),
('Table'[ClosedOn]<_closed_on && 'Table'[ClosedOn] >=_closed_minus_7) &&
'Table'[Asset] = _asset &&
'Table'[Customer] = _customer
)
)
resultados en la siguiente tabla, para mostrar el nulo, deberá indicarle al objeto visual que muestre valores en blanco
Espero que ayude
jhowe1
En respuesta a richbenmintz
Hola @richbenmintz, creo que nos estamos acercando, sin embargo, no obtengo ningún resultado de esta medida.
¿Qué me estoy perdiendo? También quiero que este recuento pueda ser dividido por ingeniero (ver código SQL) que está en una tabla diferente ‘dbo.FactBooking’
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1
¿Puede proporcionar un archivo pbix de muestra? Nos facilitaría mucho las cosas a mí y a otros miembros de la comunidad para proporcionar la respuesta correcta.
Gracias,
jhowe1
En respuesta a richbenmintz
Hola Rich,
Me acabo de dar cuenta de que está usando la medida seleccionada y solo tenía seleccionado el nombre del ingeniero y la tasa de recuperación. Repliqué el visual de su tabla (los resultados son incorrectos de todos modos, hay fechas aquí que ni siquiera están en mi tabla de factworkorder). Algunos de los datos en este conjunto de datos pueden ser confidenciales, preferiría una llamada rápida a los equipos si es posible, si el pegado no es suficiente.
y pegué mi DAX a continuación
Recall Rate =
var _closed_on = SELECTEDVALUE(WorkOrder[Closed On])
var _closed_minus_7 = DATE(YEAR(SELECTEDVALUE(WorkOrder[Closed On])), MONTH(SELECTEDVALUE(WorkOrder[Closed On])), DAY(SELECTEDVALUE(WorkOrder[Closed On]))) - 7
var _customer = SELECTEDVALUE(WorkOrder[KEY_Customer])
var _asset = SELECTEDVALUE(WorkOrder[KEY_Asset])
return
CALCULATE(
COUNTROWS(WorkOrder)
,FILTER(
ALL(WorkOrder),
(WorkOrder[Closed On] <_closed_on && WorkOrder[Closed On] >=_closed_minus_7) &&
WorkOrder[KEY_Asset] = _asset &&
WorkOrder[KEY_Customer] = _customer
)
)
SQL
SELECT
FB.KEY_Engineer,
FWO.KEY_Customer,
FWO.KEY_Asset,
FWO.ClosedOn
FROM pbi.FactWorkOrder AS FWO
JOIN pbi.FactBooking AS FB ON FB.KEY_WorkOrder = FWO.KEY_WorkOrder
WHERE FWO.WorkOrderType="Breakdown"
AND KEY_Asset IS NOT NULL
AND ClosedOn IS NOT NULL
ORDER BY ClosedOn DESC
Datos
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1,
Con los datos proporcionados, agregué una nueva condición de filtro a la medida, que nuevamente creo que proporciona el resultado deseado, cuenta los activos reparados y completados más de una vez en un período de 7 días, por el cliente y el ingeniero.
Recall Rate 2 =
var _closed_on = SELECTEDVALUE(WorkOrder[Closed On])
var _closed_minus_7 = DATE(YEAR(SELECTEDVALUE(WorkOrder[Closed On])), MONTH(SELECTEDVALUE(WorkOrder[Closed On])), DAY(SELECTEDVALUE(WorkOrder[Closed On]))) - 7
var _customer = SELECTEDVALUE(WorkOrder[KEY_Customer])
var _asset = SELECTEDVALUE(WorkOrder[KEY_Asset])
var _engineer = SELECTEDVALUE('WorkOrder'[KEY_Engineer])
return
CALCULATE(
COUNTROWS(WorkOrder)
,FILTER(
ALL(WorkOrder),
(WorkOrder[Closed On] <_closed_on && WorkOrder[Closed On] >=_closed_minus_7) &&
WorkOrder[KEY_Asset] = _asset &&
WorkOrder[KEY_Customer] = _customer &&
WorkOrder[KEY_Engineer] = _engineer
)
)
Espero que esto te ayude un poco más,
jhowe1
En respuesta a richbenmintz
Hola @richbenmintz, gracias de nuevo por tu tiempo, muy cerca ahora. Como puede ver en mi SQL, el ingeniero proviene de la tabla de reserva, no de la orden de trabajo, por lo tanto, no puedo filtrar una columna de la orden de trabajo por ingeniero. También tuve que filtrar las órdenes de trabajo que no tienen reservas y activos nulos (-1) como puede ver en mi DAX. Idealmente, lo que busco es un número (tasa de recuperación) que se pueda dividir por (es decir, un número total desglosado) el nombre del ingeniero en un elemento visual (asociado con key_engineer, del ingeniero dim), o el nombre del cliente (cliente dim) o activo. nombre (activo atenuado). La clave, etc., no tendrá sentido para el usuario, fue solo para obtener los datos correctos. ¿Cómo refactorizaríamos el DAX para admitir esto?
Recall Rate =
VAR _closed_on = SELECTEDVALUE ( WorkOrder[Closed On] )
VAR _closed_minus_7 = DATE ( YEAR ( SELECTEDVALUE ( WorkOrder[Closed On] ) ), MONTH ( SELECTEDVALUE ( WorkOrder[Closed On] ) ), DAY ( SELECTEDVALUE ( WorkOrder[Closed On] ) ) ) - 7
VAR _customer = SELECTEDVALUE ( WorkOrder[KEY_Customer] )
VAR _asset = SELECTEDVALUE ( WorkOrder[KEY_Asset] )
VAR _engineer = SELECTEDVALUE ( Booking[KEY_Engineer] )
VAR _booking = SELECTEDVALUE ( Booking[KEY_WorkOrder] )
RETURN
CALCULATE (
COUNTROWS ( WorkOrder ),
FILTER(
ALL( WorkOrder ),
( NOT( ISBLANK ( _booking ) ) && _asset <> -1 && WorkOrder[Closed On] < _closed_on
&& WorkOrder[Closed On] >= _closed_minus_7 )
&& WorkOrder[KEY_Asset] = _asset
&& WorkOrder[KEY_Customer] = _customer
)
)
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1,
Realmente necesito una copia de un archivo pbix con representación de sus datos y modelo de datos, de lo contrario, creo que solo arrojaré spagetthi a la pared.
jhowe1
En respuesta a richbenmintz
Vale, entiendo. ¿Cómo puedo subir esto? Tendré que revisar y eliminar cualquier información confidencial del modelo … o estar feliz de hacer una llamada rápida podría ser más rápido.
@richbenmintz He creado una versión básica enmascarada de mi conjunto de datos, por favor avíseme cómo puedo enviárselo lo antes posible. Gracias por toda la ayuda.
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1
comparta a través de onedrive o dropbox o cualquier herramienta para compartir archivos con la que se sienta cómodo
jhowe1
En respuesta a richbenmintz
@richbenmintz He enviado un enlace de forma privada, por lo que para el grupo verde (en la primera captura de pantalla) esperaría ver el retiro del ingeniero 797, 428, 4 cada uno. Grupo naranja Esperaría ver un recuento de 2 para 797 y 1 para 428. en un gráfico de barras apiladas, por ejemplo, simplemente con el nombre / recuperación del ingeniero. Sería bueno mostrar el recuento de 8 (grupo verde) para el nivel de cliente / activo en otra imagen, pero principalmente se trata de que los ingenieros muestren los totales correctos.
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1,
Intentaré tener una mirada más profunda hoy, lo que sí veo, sin embargo, es que tiene una relación de uno a muchos entre la reserva y la orden de trabajo, y el ingeniero vive en la reserva, ¿qué sucede si varios ingenieros trabajan en el activo? lo cerrado está en un lado de la relación, ¿quién la cerró?
jhowe1
En respuesta a richbenmintz
Muchas gracias, entonces se crea una orden de trabajo, luego se programa una reserva contra la orden de trabajo, creo que solo debería haber un ingeniero contra una reserva, crean otra orden de trabajo si necesitan enviar otro ingeniero. Sé que es uno para muchos, pero en la práctica me han dicho que solo debería haber una reserva contra una orden de trabajo. Dame un grito si tienes alguna otra pregunta. Se olvidó de agregar que estos son datos de prueba con los que están trabajando, aún no se han activado con su sistema.
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1,
Creo que gran parte del problema se debe a la forma en que se relacionan los datos, para mí la reserva es el hecho, dadas las relaciones, así que agregué el activo y cerré las claves a la tabla de reservas, luego creé una columna de cálculo que identifica si la reserva es un retiro
Recall Rate Flag =
VAR _closed_on = Booking[Closed_on]
VAR _closed_minus_7 = DATE(YEAR(Booking[Closed_on]), MONTH ( Booking[Closed_on] ), DAY (Booking[Closed_on])) - 7
VAR _customer = ( Booking[KEY_Customer] )
VAR _asset = ( Booking[KEY_Asset] )
VAR _engineer = ( Booking[KEY_Engineer] )
VAR _booking = ( Booking[KEY_WorkOrder] )
RETURN
if(CALCULATE (
COUNTROWS ( Booking ),
FILTER(
ALL( Booking ),
_asset <> -1
&& Booking[Closed_On] < _closed_on
&& Booking[Closed_On] >= _closed_minus_7
&& Booking[KEY_Asset] = _asset
&& Booking[KEY_Customer] = _customer
&& Booking[KEY_Engineer] = _engineer
)
)>0, 1)
Luego creó una medida que cuenta las reservas que son retiradas
Recall Rate New = sum('Booking'[Recall Rate Flag])
que da como resultado la imagen a continuación, es posible que deba limpiar un poco los datos al ingresar para asegurarse de tener uno a uno en la orden de trabajo y la reserva.
Puedo adjuntar el archivo aquí o enviárselo a través de mensaje privado, su elección.
Gracias
jhowe1
En respuesta a richbenmintz
Gracias de nuevo por su ayuda, se lo agradecemos mucho.
jhowe1
En respuesta a richbenmintz
Lo siento, acabo de recibir tu mensaje. La relación de reserva de orden de trabajo siempre ha sido un problema para mí, normalmente nunca tendría una relación directa entre dos tablas de hechos. El proceso es que se crea un WO, luego se programa una reserva con un ingeniero asignado. He estado usando el WO como la tabla maestra, ya que es donde comienza el proceso, sin embargo, la reserva es un grano más bajo (nivel transaccional). Creo que me he acercado al modelo de manera incorrecta, el nivel más bajo debería ser la tabla maestra. Creo que voy a intentar desactivar la relación directa entre wo / booking y usar la reserva como tabla principal y buscar los valores de nivel superior que necesito a través de sql / dax. Es molesto en todos los libros, etc., nunca hay ejemplos de servicios de campo que me parezcan más complicados que la mayoría. Puede enviarme un enlace al modelo en un mensaje privado, ¿cómo modelaría este proceso correctamente? Gracias de nuevo por la ayuda.
richbenmintz
En respuesta a jhowe1
Hola @ jhowe1,
Traería todas las claves que necesita a la tabla donde está derivando la métrica de recuperación, luego podrá obtener los valores que necesita y realizar toda la manipulación de contexto en un solo lugar. Eche un vistazo al archivo que le envié, ya que eso es lo que intenté hacer con sus datos de muestra.
jhowe1
En respuesta a richbenmintz
Hola Rich,
No estoy seguro de estos dos recuentos para la nueva tasa de recuperación en su captura de pantalla … ¿por qué?