繁体   English   中英

SQL - 获取日期的工作日范围在另一个日期范围内

[英]SQL - Getting working days of date range within another date range

我有2套日期范围:

  1. @StartDate@EndDate :传递给存储过程
  2. ProjectStartDateProjectEndDate :在数据库中

目标是获取ProjectStartDateProjectEndDate@StartDate@EndDate之间的工作日数(忽略公共假期)。

例1:

@StartDate = 2016/03/21
@EndDate = 2016/03/25

ProjectStartDate = 2016/03/13
ProjectEndDate = 2016/03/22

所以我需要计算的工作日数是ProjectStartDateProjectEndDate@StartDate@Endate -在这种情况下,工作日数应为2(星期一-星期五)

例2:

ProjectStartDate = 2016/03/22
ProjectEndDate = 2016/03/29

所以我需要计算的工作日数是ProjectStartDateProjectEndDate@StartDate@Endate之间的@Endate -在这种情况下,工作日数应为4(星期一-星期五)

例3:

ProjectStartDate = 2016/03/13
ProjectEndDate = 2016/03/29

所以我需要计算的工作日数是ProjectStartDateProjectEndDate@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM