Having a calendar table with a list of all possible dates is convenient, but in this case we can do without it.
I will summarize your question a bit. Instead of looking only at the current quarter, let you have two parameters that determine the range of dates of interest to you:
DECLARE @ParamStartDate date; DECLARE @ParamEndDate date;
First we need to get all rows from Absence that have a range from FromDate to UntilDate that intersects with the given period.
SELECT ... FROM Absence WHERE ABS_REASON='SICK'
The two periods A and B overlap when (StartA <= EndB) and (EndA >= StartB) .
Then we need to calculate how many days are at the intersection of two periods.
The intersection period cannot be greater than the specified date range (from @ParamStartDate to @ParamEndDate ).
The intersection period cannot be longer than the duration of the disease ( FromDate to UntilDate ).
So, the start of the intersection is the last of FromDate and @ParamStartDate , i.e. MAX(FromDate, @ParamStartDate)
The end of the intersection is the earliest of UntilDate and @ParamEndDate , i.e. MIN(UntilDate, @ParamEndDate)
Finally, the duration of the crossing in days
DATEDIFF(day, MAX(FromDate, @ParamStartDate), MIN(UntilDate, @ParamEndDate))
But, only if it is positive. If it is negative, it means that the period of the illness ended before the quarter began (or the illness began after the end of the quarter).
There are no built-in MIN, MAX functions that take two parameters as needed, so I use CROSS APPLY to calculate them. In addition, I calculate the number of days in a given quarter, just for completeness. The final request looks like this:
SELECT 1+DATEDIFF(day, @ParamStartDate, @ParamEndDate) AS QuarterDays ,CASE WHEN 1+DATEDIFF(day, CTE_MaxStartDate.AbsenceStartDate, CTE_MinEndDate.AbsenceEndDate) > 0 THEN 1+DATEDIFF(day, CTE_MaxStartDate.AbsenceStartDate, CTE_MinEndDate.AbsenceEndDate) ELSE 0 END AS AbsenceDays FROM Absence CROSS APPLY ( SELECT CASE WHEN UntilDate < @ParamEndDate THEN UntilDate ELSE @ParamEndDate END AS AbsenceEndDate ) AS CTE_MinEndDate CROSS APPLY ( SELECT CASE WHEN FromDate > @ParamStartDate THEN FromDate ELSE @ParamStartDate END AS AbsenceStartDate ) AS CTE_MaxStartDate WHERE ABS_REASON='SICK'
I add 1 to DATEDIFF to get the duration of one day if the start and end dates of the period are the same.