Home > Enterprise >  Looking for a way to consolidate multiple rows of time off requests to ranges in one row based off d
Looking for a way to consolidate multiple rows of time off requests to ranges in one row based off d

Time:01-05

I'm attempting to consolidate some Time off requests from multiple rows into one row which identifies the start and end time. The current table looks similar to the following;

ID hours per day Submitted Date Requested Date Requested Status
'Joe' 8 '2017-12-01' '2017-12-05' 'Approved'
'Joe' 8 '2017-12-01' '2017-12-06' 'Approved'
'Joe' 4 '2017-12-01' '2017-12-07' 'Declined'
'suzie' 8 '2018-09-08' '2017-12-24' 'Approved'
'suzie' 8 '2018-09-08' '2017-12-25' 'Approved'
'Joe' 2 '2017-12-01' '2017-12-7' 'Approved'

I'm trying to condense this into the following:

ID Total Hours Submitted Date Requested Date Start Requested Date End Requested Status
Joe 16 '2017-12-01' '2017-12-05' '2017-12-06' Approved
Joe 4 '2017-12-01' '2017-12-07' '2017-12-07' Declined
suzie 16 '2018-09-08' '2017-12-24' '2017-12-25' Approved
Joe 2 '2017-12-01' '2017-12-07' '2017-12-07' Approved

I've tried dozens of things utilizing partitions but i'm not really getting anywhere. Any suggestions?

CodePudding user response:

This is a gaps and islands problem. Assuming you are using MySQL 8 we can use the difference in row numbers method here:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY RequestedDate) rn1,
              ROW_NUMBER() OVER (PARTITION BY ID, RequestedStatus
                                 ORDER BY RequestedDate) rn2
    FROM yourTable
)

SELECT ID, SUM(hoursperday) AS total_hours, SubmittedDate,
       MIN(RequestedDate) AS rd_start, MAX(RequestedDate) AS rd_end,
       RequestedStatus
FROM cte
GROUP BY ID, SubmittedDate, RequestedStatus, rn1 - rn2
ORDER BY ID, RequestedStatus, MIN(RequestedDate);

screen capture from demo link below

Demo

  •  Tags:  
  • Related