Medida de la tasa de retiro del servicio

Un usuario Pregunto ✅

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

Captura de pantalla 2021-03-05 a las 10.29.18.png

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.

richbenmintz_0-1615484865046.png

Puedo adjuntar el archivo aquí o enviárselo a través de mensaje privado, su elección.

Gracias

Hola @ jhowe1,

v-lionel-msft_0-1615172521392.png

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?

v-lionel-msft_1-1615173140702.png

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

richbenmintz_0-1615209258167.png

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.

jhowe1_0-1615212695250.png

jhowe1_2-1615213082423.png

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

Captura de pantalla 2021-03-08 a las 15.05.20.png

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

KEY_Engineer KEY_Customer KEY_Asset ClosedOn
613 540527-1 2021-02-10 16:59:23
797 540527248 2021-02-10 16:24:35
797 540527-1 2021-02-10 16:24:17
797 540527 23537 2021-02-10 16:24:01
797 540527248 2021-02-10 16:23:14
800 540527248 2021-02-10 16:02:48
797 540527248 2021-02-10 11:55:16
477 540527248 2021-02-10 11:13:07
428 530041 2053 2021-01-29 09:29:41
428 530041 6676 2021-01-28 10:29:05
797 530041 6676 2021-01-26 11:06:03
797 530041 6676 2021-01-26 10:52:17
797 530041 6676 2021-01-25 17:54:00
797 540527 5256 2021-01-25 16:41:19
797 540527 5256 2021-01-25 15:15:50
428 533252 5592 2021-01-25 14:45:46
797 540527 14966 2021-01-25 14:38:41
428 540527 5256 2021-01-25 12:21:53
797 540527 14966 2021-01-20 16:11:23
797 530041 19987 2021-01-18 11:36:46
797 530041 19987 2021-01-15 12:07:40
428 530041 24564 2021-01-14 10:40:38
428 530041 19987 2021-01-13 12:13:32
428 540527 5256 2021-01-13 11:56:52
428 530041 19987 2021-01-13 11:38:52
428 530041 19987 2021-01-13 11:10:11
797 530041 19987 2021-01-13 10:21:15
797 540527 5256 2021-01-12 14:43:50
428 540527 5256 2021-01-12 13:49:04
797 530041 19987 2021-01-11 12:30:45
428 530041 19987 2021-01-11 11:13:42
797 530041 19987 2021-01-11 11:12:56
797 530041 19987 2021-01-08 16:48:18
797 530041 19987 2021-01-08 16:41:46
795 541084 12826 2021-01-08 08:21:34
795 533979 5135 2021-01-06 14:59:43
795 533252 10821 2021-01-06 11:49:06
795 540527 5256 2021-01-06 11:34:45
795 530041 24564 2021-01-06 11:19:50
428 530041 19987 2021-01-04 11:40:28
428 530041 19987 2021-01-04 11:26:13
428 530041 19987 2020-12-17 10:12:26
428 530041 19987 2020-12-17 10:12:26
428 530041 19987 2020-12-16 12:07:14
428 530041 19987 2020-12-15 16:39:01
428 530041 19987 2020-12-15 15:50:49
428 530041 19987 2020-12-15 13:07:31
797 530041 19987 2020-12-10 15:34:48
428 530041 19987 2020-12-04 10:29:21
800 530041 19987 2020-11-30 16:30:48
800 530041 19987 2020-11-30 16:30:48
800 530041-1 2020-11-30 16:16:02
800 530041-1 2020-11-30 16:16:02
795 530041 19987 2020-11-24 16:17:20
795 530041 19987 2020-11-24 14:42:19
795 530041 19987 2020-11-16 15:48:30
795 529402 14956 2020-11-16 15:30:34
795 529402 14956 2020-11-16 15:30:34
795 529402 14956 2020-11-16 15:30:34
795 530041 19987 2020-11-12 10:36:12
795 530041 19987 2020-11-12 10:36:12
797 530041 19987 2020-11-11 17:07:12
Las fechas adicionales en la tabla visual provienen de órdenes de trabajo que no tienen una reserva, mientras que solo me interesan las órdenes de trabajo que tienen una reserva para este cálculo.
jhowe1_0-1615219759282.png

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
       )
    )

richbenmintz_0-1615251506355.png

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
        )
    )

Captura de pantalla 2021-03-09 a las 11.01.00.png

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.

richbenmintz_0-1615484865046.png

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é? Captura de pantalla 2021-03-17 a las 16.56.20.png

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *