简体   繁体   English

在T-SQL中计算两个日期之间的工作日(扩展)

[英]Count work days between two dates in T-SQL (Extended)

Extending this question: Here 扩展这个问题: 这里

I would like to count work days between two dates in t-sql, just weekends but not the whole work day (24 hrs) just let's say from 9 AM to 5:30 PM each work day. 我想在t-sql中计算两个日期之间的工作日,只是周末,而不是整个工作日(24小时),只是说每个工作日从上午9点到下午5:30。

How can I do that using for instance CMS' approach: 我该如何使用例如CMS的方法来做到这一点:

 DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '2008/10/01'
SET @EndDate = '2008/10/31'


SELECT
   (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, @EndDate) = 'Saturday' THEN 1 ELSE 0 END)

I think you pretty well had it, just need to change the THEN 1 to THEN -1 我认为您已经拥有了它,只需要将THEN 1更改为THEN -1

However, I'm not entirely sure what you'd like to do with the hours part of your question. 但是,我不确定您要在问题的小时数部分做什么。

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '2013/03/01'
SET @EndDate = '2013/03/31'


SELECT
   (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, @EndDate) = 'Saturday' THEN -1 ELSE 0 END)

This is what I was looking for, here is the code in case someone else need it: 这是我一直在寻找的,如果有人需要它,这里是代码:

The parameters are: 参数为:

@D1 (StartDate)
@D2 (EndDate)
@T1 (Business Hours - Start)
@T2 (Business Hours - End)

The function returns a float with the amount of hours. 该函数返回带有小时数的浮点数。


CREATE FUNCTION [dbo].[WorkHoursDiff] (@D1 as datetime,@D2 as datetime,@T1 as int,@T2 as int)  
RETURNS float AS  
BEGIN 
    if @D1>@D2 return 0

    declare @whd as float

    declare @H1 as float
    declare @H2 as float


    if not (datepart(yyyy,@D1   )=datepart(yyyy,@D2) and datepart(mm,@D1)=datepart(mm,@D2) and datepart(dd,@D1)=datepart(dd,@D2))
        begin
            declare @DD as datetime
            SET @whd=0
            if datepart(dw,@D1)<>1 and datepart(dw,@D1)<>7 
                                        if dbo.GetDateHour(@D1)<@T1 SET @whd = @T2-@T1
            else if dbo.GetDateHour(@D1)>@T2 SET @whd = 0
            else if dbo.GetDateHour(@D1)>=@T1 and dbo.GetDateHour(@D1)<=@T2 SET @whd = @T2-dbo.GetDateHour(@D1)

            SET @DD=@D1 + 1
            while not (datepart(yyyy,@DD)=datepart(yyyy,@D2) and datepart(mm,@DD)=datepart(mm,@D2) and datepart(dd,@DD)=datepart(dd,@D2))
                begin
                    if not(datepart(dw,@DD)=1 or datepart(dw,@DD)=7)  
                         SET @whd=@whd + (@T2-@T1)

                    SET @DD=@DD + 1
                end
                if datepart(dw,@D2)<>1 and datepart(dw,@D2)<>7
                if dbo.GetDateHour(@D2)<@T1 SET @whd = @whd 
                else if dbo.GetDateHour(@D2)>@T2 SET @whd = @whd + @T2 - @T1
                else if dbo.GetDateHour(@D2)>=@T1  and dbo.GetDateHour(@D2)<=@T2 SET @whd = @whd +dbo.GetDateHour(@D2)-@T1

        end
    else
        begin
            if dbo.GetDateHour(@D1)<@T1 SET @H1=@T1
            else if dbo.GetDateHour(@D1)>@T2 SET @H1=@T2
            else SET @H1=dbo.GetDateHour(@D1)

            if dbo.GetDateHour(@D2)<@T1 SET @H2=@T1
            else if dbo.GetDateHour(@D2)>@T2 SET @H2=@T2
            else SET @H2=dbo.GetDateHour(@D2)

            if datepart(dw,@D1)=1 or datepart(dw,@D1)=7  SET @whd=0
            else SET @whd=@H2-@H1
        end
    return @whd

END

found this.. 找到了..

 CREATE FUNCTION dbo.GetWorkingDays
  ( @StartDate datetime,
    @EndDate datetime )
RETURNS INT
AS
BEGIN
  DECLARE @WorkDays int, @FirstPart int
  DECLARE @FirstNum int, @TotalDays int
  DECLARE @LastNum int, @LastPart int
  IF (DATEDIFF(day, @StartDate, @EndDate) < 2)
    BEGIN
      RETURN ( 0 )
    END
  SELECT
   @TotalDays = DATEDIFF(day, @StartDate, @EndDate) - 1,
   @FirstPart = CASE DATENAME(weekday, @StartDate)
                 WHEN 'Sunday' THEN 6
                 WHEN 'Monday' THEN 5
                 WHEN 'Tuesday' THEN 4
                 WHEN 'Wednesday' THEN 3
                 WHEN 'Thursday' THEN 2
                 WHEN 'Friday' THEN 1
                 WHEN 'Saturday' THEN 0
               END,
   @FirstNum = CASE DATENAME(weekday, @StartDate)
                 WHEN 'Sunday' THEN 5
                 WHEN 'Monday' THEN 4
                 WHEN 'Tuesday' THEN 3
                 WHEN 'Wednesday' THEN 2
                 WHEN 'Thursday' THEN 1
                 WHEN 'Friday' THEN 0
                 WHEN 'Saturday' THEN 0
               END
  IF (@TotalDays < @FirstPart)
     BEGIN
       SELECT @WorkDays = @TotalDays
     END
  ELSE
     BEGIN
       SELECT @WorkDays = (@TotalDays - @FirstPart) / 7
       SELECT @LastPart = (@TotalDays - @FirstPart) % 7
       SELECT @LastNum = CASE
         WHEN (@LastPart < 7) AND (@LastPart > 0) THEN @LastPart - 1
         ELSE 0
       END
       SELECT @WorkDays = @WorkDays * 5 + @FirstNum + @LastNum
     END
  RETURN ( @WorkDays )
END
GO

Try this 尝试这个

Declare @startdate datetime,
@enddate datetime,
@countSunday int,
@countTuesday int,
@countWednesday int,@countThursday int,@countFriday int,@countSaturday int

set @countSunday=0
set @countMonday=0
set @countTuesday =0
set @countWednesday =0
set @countThursday =0
set @countFriday =0
set @countSaturday=0
set @startdate='2018-10-01'
set @enddate='2018-10-20'

while @startdate<=@enddate
Begin
    IF DatePart(WEEKDAY,@startdate) = 1
    SET @countSunday=@countSunday+1
    else if  DatePart(WEEKDAY,@startdate) = 2
      SET @countMonday=@countMonday+1  
      else if  DatePart(WEEKDAY,@startdate) = 3
      SET @countTuesday=@countTuesday+1  
      else if  DatePart(WEEKDAY,@startdate) = 4
      SET @countWednesday=@countWednesday+1  
      else if  DatePart(WEEKDAY,@startdate) = 5
      SET @countThursday=@countThursday+1  
      else if  DatePart(WEEKDAY,@startdate) = 6
      SET @countFriday=@countFriday+1  
      else if  DatePart(WEEKDAY,@startdate) = 7
      SET @countSaturday=@countSaturday+1  
    SET @startdate=DateAdd(d,1,@startdate)
END


select @countSunday as Sunday ,@countMonday as Monday,@countTuesday as Tuesday,@countWednesday as Wednesday,@countThursday as Thursday,@countFriday as Friday,@countSaturday as Saturday

Try this 尝试这个

DECLARE @DateFrom DateTime ='20181001' , @DateTo DateTime = '20181031'  ;
WITH CTE(dt)
AS
(
SELECT @DateFrom
UNION ALL
SELECT DATEADD(d, 1, dt) FROM CTE
  WHERE dt < @DateTo
)
SELECT datename("dw", dt) as Days,count(datename("dw", dt)) as numberofDays FROM CTE 
group by datename ("dw", dt)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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