가능한 모든 날짜의 목록이있는 달력 테이블을 갖는 것은 편리하지만,이 경우 우리는 그것없이 할 수 있습니다.
질문을 일반화 해 드리겠습니다. 대신 이번 분기에서 바로보고의에서의 당신이 관심이 날짜의 범위를 정의하는 두 개의 매개 변수를 보자 : 우리가 FromDate
에서 UntilDate
의 범위를 Absence
에서 모든 행을 얻을 필요가 먼저
DECLARE @ParamStartDate date;
DECLARE @ParamEndDate date;
그 주어진 기간과 교차합니다.
SELECT
...
FROM
Absence
WHERE
ABS_REASON='SICK'
-- all absence periods, which overlap with the given period
AND FromDate <= @ParamEndDate
AND UntilDate >= @ParamStartDate
두 기간 A와 B의 겹치는 경우 및 (StartA <= EndB)
(EndA >= StartB)
.
그러면 두 기간의 교집합 일 수를 계산해야합니다.
교차로는 주어진 날짜 범위보다 클 수 없습니다 (@ParamStartDate
에서 @ParamEndDate
).
교차로는 병의 길이보다 클 수 없습니다 (FromDate
에서 UntilDate
).
그래서, 교차로의 시작, FromDate
및 @ParamStartDate
의 최신 즉 MAX(FromDate, @ParamStartDate)
교차로의 결말은의, 즉 MIN(UntilDate, @ParamEndDate)
마지막으로, 기간, UntilDate
및 @ParamEndDate
의 초기입니다 일의 교차로는
DATEDIFF(day, MAX(FromDate, @ParamStartDate), MIN(UntilDate, @ParamEndDate))
입니다. 단, 양수인 경우에만 가능합니다. 부정적이라면 해당 분기가 시작되기 전에 병가 기간이 끝났음을 의미합니다 (또는 해당 분기가 끝난 후 병이 시작됨).
필요에 따라 두 개의 매개 변수를 사용하는 MIN, MAX 함수가 내장되어 있지 않으므로이 매개 변수를 계산하려면 CROSS APPLY
을 사용합니다. 또한, 주어진 분기의 일 수를 계산하여 완성도를 계산합니다. 마지막 쿼리는 다음과 같습니다
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'
-- all absence periods, which overlap with the given period
AND FromDate <= @ParamEndDate
AND UntilDate >= @ParamStartDate
나는 기간의 시작 날짜와 종료 날짜가 같은 경우 1 일의 기간을 얻을 수 DATEDIFF
에 1을 추가합니다.
'ABSENCE'테이블의 샘플 데이터를 공유 할 수 있습니까? –
분기가 끝나기 전에 시작하여 분기가 시작된 후에 끝난 모든 결석이 필요합니다 (그들이 언제 돌아 오는지 모를 경우 'NULL'입니다). 따라서 WHERE 절은 다음과 같습니다. 올바른 ('NULL'' UNTILDATE'를 처리 할 필요가 없다면). 그러면 현재 분기 및 부재 범위 내의 일 수를 계산해야하며 이에 대해 Rob Farley가 제안한대로 작업 일을 알 필요가 있습니다. –