The method I have used here is a Tally Table to create extra rows. I JOIN
onto the tally table where the number of hours / 24 (integer maths is useful) is greater than the tally number, and then can use that to calculate the hours.
WITH YourTable AS(
SELECT *
FROM (VALUES(1,CONVERT(date,'2018/01/24',111),4 ),
(2,CONVERT(date,'2018/03/21',111),40),
(3,CONVERT(date,'2018/08/16',111),33),
(4,CONVERT(date,'2018/12/01',111),8 ),
(5,CONVERT(date,'2018/12/17',111),56 ),
(6,CONVERT(date,'2018/12/17',111),24 ))V(VacationID,VacationDate,VacationDuration_Hr)),
--Solution
N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1, N N2) -- 25 days, add more for more days
SELECT YT.VacationID,
DATEADD(DAY, T.I, YT.VacationDate) AS VacationDate,
CASE WHEN VacationDuration_Hr - (T.I * 24) > 24 THEN 24 ELSE YT.VacationDuration_Hr - (T.I * 24) END AS VacationDuration_Hr
FROM YourTable YT
JOIN Tally T ON (YT.VacationDuration_Hr -1) / 24 >= T.I
ORDER BY YT.VacationID,
T.I;
You could also use an rCTE here instead, however, I tend to avoid those for things like this; especially when I have no context of what the upper limit to the value of VacationDuration_Hr
could be. if it is large it could have some nasty performance implications and a Tally will significantly out perform the RBAR nature of an rCTE.
5
solved Break down long multi day periods of time into several single day periods