Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Join us for an expert-led overview of the tools and concepts you'll need to become a Certified Power BI Data Analyst and pass exam PL-300. Register now.

Reply
TerriAki
Frequent Visitor

Consecutive streak into a date range

Hi,  

 

Kinda new here and would really appreciate some help 🙂

 

I have a time and attendance table and trying to work out the continues period of sick absence with a value of S, SC or SB for each employee.  Start and End added below as an example of what the output should be (could be summarised into a seperate table if needed.  In order to work out continous periods of absence the calculation will need to take into account two tables of codes. One contains a list of codes that would break a continuous period and another list which does not.  

 

The streak must start and end S, SB or SC.

 

T&A table 

Employee IDDate            Status    Start             End
12302-Feb-22RD  
12303-Feb-221  
12304-Feb-22S04/02/202204/02/2022
12305-Feb-22RD  
12306-Feb-22RD  
12307-Feb-221  
12308-Feb-22S  
12309-Feb-22SC  
12310-Feb-22SB08/02/202210/02/2022

123

11-Feb-221  
12312-Feb-22RD  
12313-Feb-22RD  
12314-Feb-22AL  
12315-Feb-22S  
12316-Feb-22RD  
12317-Feb-22S  
12318-Feb-22S  
12319-Feb-22ME  
12320-Feb-22RD  
12321-Feb-22S  
12322-Feb-22S15/02/202222/02/2022
12323-Feb-22RD  

 

Break codes Continuous codes
01 AW
ET BH
L HA
NW ME
RW OD
RX RD
TC RB
TW BL
WB HR
WS PL
XX S
ZL SB
AB SC
AL  
AS  
CL  
EL  
FL  
HD  
HL  
LC  
MB  
ML  
TA  
UL  
1 ACCEPTED SOLUTION

Hi @TerriAki 
I was able to double the speed by creating relationships as per below screenshot. I tried on 2.7M rows table and still takes around 50-55 sec. on my machine which is not super-fast. Still too slow and also you have to know that the time increases exponentially with the number of rows and I have no idea how many columns you have. If you have too many columns we need to select only the relevant ones
1.png

Start - End = 
IF (
    'T&A table 2'[Status] IN 'Sick Absence Code',
    VAR CurrentDate = 
        'T&A table 2'[Date]
    VAR EmployeeTable =
        CALCULATETABLE ( 'T&A table 2',  ALLEXCEPT ( 'T&A table 2', 'T&A table 2'[Employee ID] ) )
    VAR OffDaysTable =
        CALCULATETABLE ( 'T&A table 2', ALLEXCEPT ( 'T&A table 2','T&A table 2'[Employee ID] ), 'Sick Absence Code' )
    VAR BreakDaysTable = 
        CALCULATETABLE ( 'T&A table 2', ALLEXCEPT ( 'T&A table 2','T&A table 2'[Employee ID] ), 'Break codes' )
    -- Calculating last day off 
    VAR NexBreaksTable = 
        FILTER ( BreakDaysTable, 'T&A table 2'[Date] >= CurrentDate )
    VAR NextBreakDate =
        MINX ( NexBreaksTable, 'T&A table 2'[Date] )
    VAR NextOffDaysTable =
        FILTER ( OffDaysTable, 'T&A table 2'[Date] < NextBreakDate )
    VAR LastDayOff =
        MAXX ( NextOffDaysTable, 'T&A table 2'[Date] )
    RETURN
        IF (
            CurrentDate = LastDayOff,
            -- Calculating first day off 
            VAR PreviousBreaksTable = 
                FILTER ( BreakDaysTable, 'T&A table 2'[Date] <= CurrentDate )
            VAR PreviousBreakDate =
                MAXX ( PreviousBreaksTable, 'T&A table 2'[Date] )
            VAR PreviousOffDaysTable =
                FILTER ( OffDaysTable, 'T&A table 2'[Date] > PreviousBreakDate )
            VAR FirstDayOff = 
                MINX ( PreviousOffDaysTable, 'T&A table 2'[Date] )
            VAR Result =
                    FirstDayOff & " - " & LastDayOff
            RETURN
                Result
        )
)

View solution in original post

11 REPLIES 11
tamerj1
Super User
Super User

Hi @TerriAki 
Please find attached sample file with the solution https://www.dropbox.com/t/WHjQ0GfVCTQ62ua7
It is not the optimum performance code but it should work and do the job.

At the end of the sample data I have added a break as otherwise the sick leave is considred open. I hope this shall not be a problem to you.
I will let you know If I was able to optimize it further
1.png

Start - End = 
IF (
    'T&A table'[Status] IN { "S", "SB", "SC" },
    VAR CurrentDate = 
        'T&A table'[Date]
    VAR EmployeeTable =
        CALCULATETABLE ( 'T&A table', ALLEXCEPT ( 'T&A table', 'T&A table'[Employee ID] ) )
    VAR OffTable =
        FILTER ( EmployeeTable, 'T&A table'[Status] IN { "S", "SB", "SC" } )
    VAR BreakTable = 
        FILTER ( EmployeeTable,'T&A table'[Status] IN 'Break codes' )
    -- Calculating last day off 
    VAR NextDaysTable = 
        FILTER ( EmployeeTable, 'T&A table'[Date] >= CurrentDate )
    VAR NexBreaksTable =
        FILTER ( NextDaysTable, 'T&A table'[Status] IN 'Break codes' )
    VAR NextBreakDate =
        MINX ( NexBreaksTable, 'T&A table'[Date] )
    VAR NextOffDaysTable =
        FILTER ( OffTable, 'T&A table'[Date] < NextBreakDate )
    VAR LastDayOff =
        MAXX ( NextOffDaysTable, 'T&A table'[Date] )
    -- Calculating first day off 
    VAR PreviousDaysTable = 
        FILTER ( EmployeeTable, 'T&A table'[Date] <= CurrentDate )
    VAR PreviousBreaksTable =
        FILTER ( PreviousDaysTable, 'T&A table'[Status] IN 'Break codes' )
    VAR PreviousBreakDate =
        MAXX ( PreviousBreaksTable, 'T&A table'[Date] )
    VAR PreviousOffDaysTable =
        FILTER ( OffTable, 'T&A table'[Date] > PreviousBreakDate )
    VAR FirstDayOff = 
        MINX ( PreviousOffDaysTable, 'T&A table'[Date] )
    VAR Result =
        IF (
            CurrentDate = LastDayOff,
            FirstDayOff & " - " & LastDayOff
        )
    RETURN
        Result
)

@tamerj1 Amazing!  This is very close and is reliably producing the result, is there any way to adapt the code to give the open ended absence a date too?   Also the optimisation would be really appreciated as will be running this on very large dataset.  

@TerriAki 

The problem is that most probably addapting open end absence would affect the preformance but I wIll gove a try. Meanwhile, plea

 try on your full set of data and let me know how the performance is. 

I think I can handle the open ended absence by getting Power Query to put in a final row for each Employee with a break code.   Regarding optimisation, it currently isnt running on the full dataset due to running out of memory (I have 16 GB ram and have manually tried increasing Power BI cache settings).   

Hi @TerriAki 
I was able to double the speed by creating relationships as per below screenshot. I tried on 2.7M rows table and still takes around 50-55 sec. on my machine which is not super-fast. Still too slow and also you have to know that the time increases exponentially with the number of rows and I have no idea how many columns you have. If you have too many columns we need to select only the relevant ones
1.png

Start - End = 
IF (
    'T&A table 2'[Status] IN 'Sick Absence Code',
    VAR CurrentDate = 
        'T&A table 2'[Date]
    VAR EmployeeTable =
        CALCULATETABLE ( 'T&A table 2',  ALLEXCEPT ( 'T&A table 2', 'T&A table 2'[Employee ID] ) )
    VAR OffDaysTable =
        CALCULATETABLE ( 'T&A table 2', ALLEXCEPT ( 'T&A table 2','T&A table 2'[Employee ID] ), 'Sick Absence Code' )
    VAR BreakDaysTable = 
        CALCULATETABLE ( 'T&A table 2', ALLEXCEPT ( 'T&A table 2','T&A table 2'[Employee ID] ), 'Break codes' )
    -- Calculating last day off 
    VAR NexBreaksTable = 
        FILTER ( BreakDaysTable, 'T&A table 2'[Date] >= CurrentDate )
    VAR NextBreakDate =
        MINX ( NexBreaksTable, 'T&A table 2'[Date] )
    VAR NextOffDaysTable =
        FILTER ( OffDaysTable, 'T&A table 2'[Date] < NextBreakDate )
    VAR LastDayOff =
        MAXX ( NextOffDaysTable, 'T&A table 2'[Date] )
    RETURN
        IF (
            CurrentDate = LastDayOff,
            -- Calculating first day off 
            VAR PreviousBreaksTable = 
                FILTER ( BreakDaysTable, 'T&A table 2'[Date] <= CurrentDate )
            VAR PreviousBreakDate =
                MAXX ( PreviousBreaksTable, 'T&A table 2'[Date] )
            VAR PreviousOffDaysTable =
                FILTER ( OffDaysTable, 'T&A table 2'[Date] > PreviousBreakDate )
            VAR FirstDayOff = 
                MINX ( PreviousOffDaysTable, 'T&A table 2'[Date] )
            VAR Result =
                    FirstDayOff & " - " & LastDayOff
            RETURN
                Result
        )
)

@tamerj1  Speed is much better now and works with my large dataset however the result is not right.  The original code was accurate.   Sample attached, you can see original code in column 'T&A Table'[Start - End (v1)] and new code in 'T&A Table'[Start - End (v2)].

 

https://drive.google.com/file/d/1niL5GdrIXRIVKw6DYfrYDVu5qpgkuTsU/view?usp=sharing 

Hi @TerriAki 
Everything is find, you just missed a relationship 🙂
2.png1.png

@tamerj1 Sorry I missed that, your solution has worked out great.  I thought I might have found the limit of what DAX was capable of but your code is a work of art!  

Alright

I have some ideas. Will send you something tomorrow morning

TerriAki
Frequent Visitor

@amitchandak Thank you.  You are right, it is a continuous streak problem.  I will retitle the post so its more clearer.  

amitchandak
Super User
Super User

@TerriAki , This seems like a Continuous Streak problem. But, looking at code I am not able related you ranges

 

https://community.powerbi.com/t5/Community-Blog/Power-BI-Continuous-Streak-With-One-Day-Break/ba-p/1...

 

or

 

Continuous streak: https://youtu.be/GdMcwvdwr0o

Full Power BI Video 20 Hours YouTube
Microsoft Fabric Series 60+ Videos YouTube
Microsoft Fabric Hindi End to End YouTube

Helpful resources

Announcements
Join our Fabric User Panel

Join our Fabric User Panel

This is your chance to engage directly with the engineering team behind Fabric and Power BI. Share your experiences and shape the future.

June 2025 Power BI Update Carousel

Power BI Monthly Update - June 2025

Check out the June 2025 Power BI update to learn about new features.

June 2025 community update carousel

Fabric Community Update - June 2025

Find out what's new and trending in the Fabric community.