Calculating days to excluding weekends (Monday to Friday) in SQL Server

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

How can I calculate the number of work days between two dates from table (from the 1st row to the end) in SQL Server 2008?

I tried something like this, but it does not work

DECLARE @StartDate as DATETIME, @EndDate as DATETIME  Select @StartDate = date2 from testtable ; select @EndDate = date1 from testtable ;  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) 

回答1:

I would always recommend a Calendar table, then you can simply use:

SELECT  COUNT(*) FROM    dbo.CalendarTable WHERE   IsWorkingDay = 1 AND     [Date] > @StartDate AND     [Date] 

Since SQL has no knowledge of national holidays for example the number of weekdays between two dates does not always represent the number of working days. This is why a calendar table is a must for most databases. They do not take a lot of memory and simplify a lot of queries.

But if this is not an option then you can generate a table of dates relatively easily on the fly and use this

SET DATEFIRST 1; DECLARE @StartDate DATETIME = '20131103',          @EndDate DATETIME = '20131104';  -- GENERATE A LIST OF ALL DATES BETWEEN THE START DATE AND THE END DATE WITH AllDates AS (   SELECT  TOP (DATEDIFF(DAY, @StartDate, @EndDate))             D = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.Object_ID), @StartDate)     FROM    sys.all_objects a             CROSS JOIN sys.all_objects b ) SELECT  WeekDays = COUNT(*) FROM    AllDates WHERE   DATEPART(WEEKDAY, D) NOT IN (6, 7); 

EDIT

If you need to calculate the difference between two date columns you can still use your calendar table as so:

SELECT  t.ID,         t.Date1,         t.Date2,         WorkingDays = COUNT(c.DateKey) FROM    TestTable t         LEFT JOIN dbo.Calendar c             ON c.DateKey >= t.Date1             AND c.DateKey 

Example on SQL-Fiddle



回答2:

This does it excluding the days out but date part rather than description. You can substitute the parameters used as an example for the values in your query.

Declare      @startdate datetime = '2013-11-01',      @enddate datetime = '2013-11-11'   SELECT    (DATEDIFF(dd, @StartDate, @EndDate) + 1)   -(DATEDIFF(wk, @StartDate, @EndDate) * 2)   -(case datepart(dw, @StartDate)+@@datefirst when 8 then 1 else 0 end)    -(case datepart(dw, @EndDate)+@@datefirst when 7 then 1 when 14 then 1 else 0 end)   Returns 7 


回答3:

To add to GarethD's answer - I put together the SQL for a USA version of the Calendar table, with all holidays and weekends set to is_working_day = false... for anyone that would like the SQL, here it is:

declare @start_dt as date = '1/1/2009';     -- Date from which the calendar table will be created. declare @end_dt as date = '1/1/2030';       -- Calendar table will be created up to this date (not including).  create table CalendarTable (  date_id date primary key,  date_year smallint,  date_month tinyint,  date_day tinyint,  weekday_id tinyint,  weekday_nm varchar(10),  month_nm varchar(10),  day_of_year smallint,  quarter_id tinyint,  first_day_of_month date,  last_day_of_month date,  start_dts datetime,  end_dts datetime,  week_number_of_month int,  is_working_day bit, )  while @start_dt 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!