Forum Discussion

bigrods's avatar
bigrods
Helper III
6 months ago
Solved

Calculate Rolling Sickness Rate From Cumulative DataSet

Hi All,

Hoping anyone can help - I have 3 tables, one of Employees, one of Sickness Absences, one Calendar and I would like to calculate a Rolling 12 month sickness absence % for each month; the issue is that the Employee data is cumulative, so for every month of the year we have an appended list of employees in the organisation with the FTE hours and the Site they work at.

The issue I'm not sure on is how to accurately calculate an Available FTE calculation with the cumulative data as employees are duplicated. Some times this is necessary as some employees can change their FTE from month to month.

 

As an example - each employee from each month is listed, with duplication - but e.g. James Johnson is listed as 1 FTE in Jan-26 and 0.8 FTE in Feb-26:

Employee No.First NameSurnameFTEMonthStart DateTermination Date
123456MikeJones1Dec-2504/12/2013 
789654SueWhite0.6Dec-2517/04/2022 
988765JamesJohnson1Dec-2522/07/2025 
326598DavidWilliams1Dec-2519/08/2025 
123456MikeJones1Jan-2604/12/2013 
789654SueWhite0.6Jan-2617/04/2022 
988765JamesJohnson1Jan-2622/07/2025 
456789MartinGraham1Jan-2604/01/2026 
326598DavidWilliams1Jan-2619/08/202515/01/2026
123456MikeJones1Feb-2604/12/2013 
789654SueWhite0.6Feb-2617/04/202215/02/2026
988765JamesJohnson0.8Feb-2622/07/2025 
456789MartinGraham1Feb-2604/01/2026 

 

Sickness

Employee NumberAbsence Start DateAbsence End DateCalendar Days LostFTE Lost
12345610/11/202512/11/202533
79865401/08/202516/09/20254728.2
98876504/09/202504/09/202510.8

 

I have successfully managed to calculate this based on, if the employee table had 1 row per employee but I am unsure on how to do this with the appended dataset. My issue with 1 row per employee is that I only get one FTE per person but I need to be able to calculate each employee individually for each month. I toyed with the idea of removing duplicates in PowerQuery but this would still potentially leave duplicate entries of employees if they have more than 1 entry for different FTE's I think.

I hope anyone could please help - many thanks!

  • Step 1) Create a proper Star-Schema model based on the data you have

     

    Since you have only 2 tables here you need to create dims and fact via PowerQuery. First create Employee and Date dimensions and create a proper FactSickness table to allocate your sickness data on a daily grain.

     

    Step 2) Create required measures

    Available FTE (Month) = 
    VAR mStart = MAX ( DimDate[MonthStart] )
    VAR mEnd   = EOMONTH ( mStart, 0 )
    RETURN
    CALCULATE (
        SUM ( FactEmployee[FTE] ),
        FILTER (
            FactEmployee,
            FactEmployee[Start Date] <= mEnd
                && ( ISBLANK ( FactEmployee[Termination Date] )
                     || FactEmployee[Termination Date] >= mStart )
        )
    )
    
    Available FTE (Rolling 12M) = 
    CALCULATE (
        [Available FTE (Month)],
        DATESINPERIOD ( DimDate[MonthStart], MAX ( DimDate[MonthStart] ), -12, MONTH )
    )
    
    Sickness Lost (Rolling 12M) = 
    CALCULATE (
        SUM ( FactSickness[DailyFTE_Lost] ),
        DATESINPERIOD ( DimDate[Date], MAX ( DimDate[Date] ), -12, MONTH )
    )
    
    Sickness Rate % (Rolling 12M) = 
    DIVIDE ( [Sickness Lost (Rolling 12M)], [Available FTE (Rolling 12M)] )

     

    Step 3) Create your visual using correct field values

     

    Please fint the attached .pbix file for end-to-end solution.

6 Replies

  • Step 1) Create a proper Star-Schema model based on the data you have

     

    Since you have only 2 tables here you need to create dims and fact via PowerQuery. First create Employee and Date dimensions and create a proper FactSickness table to allocate your sickness data on a daily grain.

     

    Step 2) Create required measures

    Available FTE (Month) = 
    VAR mStart = MAX ( DimDate[MonthStart] )
    VAR mEnd   = EOMONTH ( mStart, 0 )
    RETURN
    CALCULATE (
        SUM ( FactEmployee[FTE] ),
        FILTER (
            FactEmployee,
            FactEmployee[Start Date] <= mEnd
                && ( ISBLANK ( FactEmployee[Termination Date] )
                     || FactEmployee[Termination Date] >= mStart )
        )
    )
    
    Available FTE (Rolling 12M) = 
    CALCULATE (
        [Available FTE (Month)],
        DATESINPERIOD ( DimDate[MonthStart], MAX ( DimDate[MonthStart] ), -12, MONTH )
    )
    
    Sickness Lost (Rolling 12M) = 
    CALCULATE (
        SUM ( FactSickness[DailyFTE_Lost] ),
        DATESINPERIOD ( DimDate[Date], MAX ( DimDate[Date] ), -12, MONTH )
    )
    
    Sickness Rate % (Rolling 12M) = 
    DIVIDE ( [Sickness Lost (Rolling 12M)], [Available FTE (Rolling 12M)] )

     

    Step 3) Create your visual using correct field values

     

    Please fint the attached .pbix file for end-to-end solution.

    • bigrods's avatar
      bigrods
      Helper III

      Hi cengizhanarslan - I amended the measures slightly as I had to take into account the dates when the FTE changed for staff members but this has worked, thank you so much!

  • To calculate a rolling 12-month sickness percentage with cumulative, duplicated employee data, you must calculate Available FTE on a month-by-month basis, then sum these values over a 12-month rolling period. Using Pivot Tables or Power Query is best, ensuring you sum FTE by Month/Employee ID before calculating the rolling total.
    Step-by-Step Approach:
    1. Clean and Organize Data: Ensure all tables have a consistent "Month" identifier (e.g., end of month date).
    2. Calculate Monthly Available FTE (Solving Duplication):
    Do not just sum the FTE column. Because employees are duplicated with different FTEs per month, create a Pivot Table.
    Rows: Month, Employee ID
    Values: Max of FTE (or Average of FTE if they have multiple entries in one month).
    Alternative (Power Query): Group by Month and Employee ID, taking the maximum FTE to ensure one accurate entry per person per month.
    3. Sum Total Available FTE (12-Month Roll): Use a SUMIFS formula or a Pivot Table to sum the Monthly FTE figures calculated above for the 12-month period preceding the report date.
    4. Calculate Sickness Days: Aggregate total sickness days from the Sickness Table for the same 12-month rolling period.
    5. Calculate %:

    Note: If sickness is measured in days, convert FTE to days (e.g., FTE x 21.67
    average working days per month).

    This ensures that if an employee changed from 0.5 FTE in January to 1 FTE in February, those changes are captured correctly by the specific month, rather than double-counted.

    • bigrods's avatar
      bigrods
      Helper III

      Thanks so much for your reply, I tried the first reply and this worked successfully

  • I don't think that the employee table is the problem so much as the sickness table - that is potentially split across multiple months. One solution would be to split each absence into separate rows, with one row for each month affected. You could create a calculated table like

    Monthly Sickness Table =
    SELECTCOLUMNS(
        GENERATE(
            Sickness,
            VAR StartDate = Sickness[Absence Start Date]
            VAR EndDate = Sickness[Absence End Date]
            VAR NumDaysSick = Sickness[Calendar Days Lost]
            VAR FTEDaysSick = Sickness[FTE Lost]
            VAR SickDays = DATESBETWEEN( 'Date'[Date], StartDate, EndDate )
            VAR DaysAndMonth = SELECTCOLUMNS(
                FILTER(
                    'Date',
                    'Date'[Date] IN SickDays
                ),
                'Date'[Date],
                'Date'[Start Of Month]
            )
            VAR MonthWithDayCount = ADDCOLUMNS( 
                GROUPBY(
                    DaysAndMonth,
                    'Date'[Start Of Month],
                    "@Num days", SUMX( CURRENTGROUP(), 1 )
                ),
                "FTE Sick Days", 
                VAR Ratio = DIVIDE( [@Num days], NumDaysSick )
                VAR Result = Ratio * FTEDaysSick
                RETURN Result
            )
            RETURN MonthWithDayCount
        ),
        Sickness[Employee Number],
        'Date'[Start Of Month],
        [FTE Sick Days]
    )

    Then make sure that your date table is linked to the new Monthly Sickness table and the employee table and you could write a measure like

    Absence % 12 month average =
    VAR DatesToUse =
        DATESINPERIOD ( 'Date'[Start of month], TODAY (), -12, MONTH )
    VAR DatesWithAbsenceData =
        ADDCOLUMNS (
            DatesToUse,
            "@sickness", CALCULATE ( SUM ( 'Monthly Sickness'[FTE Sick Days] ) ),
            "@fte days available",
                VAR NumWorkingDays =
                    CALCULATE ( COUNTROWS ( 'Date' ), KEEPFILTERS ( 'Date'[Is Working Day] = 1 ) )
                VAR FTE =
                    CALCULATE ( SUM ( Employees[FTE] ) )
                VAR Result = NumWorkingDays * FTE
                RETURN
                    Result
        )
    VAR Result =
        AVERAGEX ( DatesWithAbsenceData, DIVIDE ( [@sickness], [@fte days available] ) )
    RETURN
        Result
    
    • bigrods's avatar
      bigrods
      Helper III

      Thanks so much for your reply, I tried the first reply and this worked successfully