[英]SQL - Getting working days of date range within another date range
我有2套日期范围:
@StartDate
和@EndDate
:传递给存储过程 ProjectStartDate
和ProjectEndDate
:在数据库中 目标是获取ProjectStartDate
和ProjectEndDate
在@StartDate
和@EndDate
之间的工作日数(忽略公共假期)。
例1:
@StartDate = 2016/03/21
@EndDate = 2016/03/25
ProjectStartDate = 2016/03/13
ProjectEndDate = 2016/03/22
所以我需要计算的工作日数是ProjectStartDate
和ProjectEndDate
在@StartDate
和@Endate
-在这种情况下,工作日数应为2(星期一-星期五)
例2:
ProjectStartDate = 2016/03/22
ProjectEndDate = 2016/03/29
所以我需要计算的工作日数是ProjectStartDate
和ProjectEndDate
在@StartDate
和@Endate
之间的@Endate
-在这种情况下,工作日数应为4(星期一-星期五)
例3:
ProjectStartDate = 2016/03/13
ProjectEndDate = 2016/03/29
所以我需要计算的工作日数是ProjectStartDate
和ProjectEndDate
在@StartDate
和@Endate
之间的@Endate
-在这种情况下,工作日数应为5(星期一-星期五)
我必须计算出工作日的代码如下:
(DATEDIFF(dd, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) + 1)
-(DATEDIFF(wk, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) * 2)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Saturday' THEN 1 ELSE 0 END)
我试图得到结果,但它部分有效。 我知道有一种更简单的方法:
CASE WHEN(CASE WHEN @StartDate <= ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)
THEN (DATEDIFF(dd, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), @EndDate) + 1)
-(DATEDIFF(wk, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), @EndDate) * 2)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Saturday' THEN 1 ELSE 0 END)
ELSE (DATEDIFF(dd, @StartDate, ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) + 1)
-(DATEDIFF(wk, @StartDate, ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) * 2)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Saturday' THEN 1 ELSE 0 END) END) >= 5
THEN 5
ELSE (CASE WHEN @StartDate <= ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)
THEN (DATEDIFF(dd, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), @EndDate) + 1)
-(DATEDIFF(wk, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), @EndDate) * 2)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Saturday' THEN 1 ELSE 0 END)
ELSE (DATEDIFF(dd, @StartDate, ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) + 1)
-(DATEDIFF(wk, @StartDate, ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) * 2)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Saturday' THEN 1 ELSE 0 END) END) END AS DaysCalculated
看来,我最终找到了答案。 我宁愿找到一种更清洁,更整洁的方式...但是我不能花更多的时间在此上,并且现在可以使用。 如果任何人有更干净,更整洁的选择,请告诉我。 谢谢。
(CASE WHEN ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart) >= @StartDate AND
ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd) >= @EndDate
THEN
(DATEDIFF(dd, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), @EndDate) + 1)
-(DATEDIFF(wk, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), @EndDate) * 2)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Saturday' THEN 1 ELSE 0 END)
ELSE
(CASE WHEN ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart) >= @StartDate AND
ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd) <= @EndDate
THEN
(DATEDIFF(dd, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) + 1)
-(DATEDIFF(wk, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart), ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) * 2)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart)) = 'Saturday' THEN 1 ELSE 0 END)
ELSE
(CASE WHEN ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart) <= @StartDate AND
ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd) <= @EndDate
THEN
(DATEDIFF(dd, @StartDate, ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) + 1)
-(DATEDIFF(wk, @StartDate, ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd)) * 2)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Saturday' THEN 1 ELSE 0 END)
ELSE
(CASE WHEN ISNULL(AA.DDAreaActivityActualStart,AA.DDAreaActivityPlannedStart) <= @StartDate AND
ISNULL(AA.DDAreaActivityActualEnd,AA.DDAreaActivityPlannedEnd) >= @EndDate
THEN
(DATEDIFF(dd, @StartDate, @EndDate) + 1)
-(DATEDIFF(wk, @StartDate, @EndDate) * 2)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Saturday' THEN 1 ELSE 0 END)
END) END) END) END) AS CalculatedDays
这个怎么样
declare @StartDate date = '2016-03-21',
@EndDate date = '2016-03-25'
; with tbl (ProjectStartDate , ProjectEndDate) as
(
select '2016-03-13', '2016-03-22' union all
select '2016-03-22', '2016-03-29' union all
select '2016-03-13', '2016-03-29'
)
select *,
[working days] = datediff( day,
case when ProjectStartDate > @StartDate then ProjectStartDate else @StartDate end,
case when ProjectEndDate < @EndDate then ProjectEndDate else @EndDate end
) + 1
from tbl
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.