Возвращает количество дней недели между двумя датами в T-SQL - PullRequest
2 голосов
/ 21 июня 2011

У меня есть 2 даты, и я хочу знать, сколько рабочих дней (пн-пт):

например,

thu jan 1 20xx    
fri jan 2 20xx    
sat jan 3 20xx    
sun jan 4 20xx    
mon jan 5 20xx  

1 января, 5 января вернется 3

(может игнорировать государственные праздники)

Ответы [ 6 ]

1 голос
/ 21 июня 2011

Если предположить, что даты не могут быть более пяти с половиной лет друг от друга (или использовать собственную таблицу подсчета вместо master..spt_values):

DECLARE @date1 datetime, @date2 datetime;
SET @date1 = '20110901';
SET @date2 = '20110905';

SELECT COUNT(*)
FROM (
  SELECT
    Date = DATEADD(day, number, @date1)
  FROM master..spt_values
  WHERE type = 'P'
    AND number between 0 AND DATEDIFF(day, @date1, @date2)
) s
WHERE DATENAME(DW, Date) NOT IN ('Saturday', 'Sunday')
1 голос
/ 21 июня 2011

попробуйте это:

SET DATEFIRST 1
DECLARE @StartDate datetime
       ,@EndDate datetime
SELECT @StartDate='6/21/2011'
      ,@EndDate='6/28/2011'
;with AllDates AS
(
    SELECT @StartDate AS DateOf, datepart(weekday,getdate()) AS WeekDayNumber
    UNION ALL
    SELECT DateOf+1, datepart(weekday,DateOf+1)
        FROM AllDates
    WHERE DateOf<@EndDate
)
SELECT COUNT(*) AS WeekDayCount FROM AllDates WHERE WeekDayNumber<=5

ВЫХОД:

WeekDayCount
------------
6

(1 row(s) affected)

Если у вас есть праздничный стол, вы можете присоединиться к нему и удалить его.

РЕДАКТИРОВАТЬ на основе комментария @Ross Watson:

SET DATEFIRST 1
DECLARE @StartDate datetime
       ,@EndDate datetime
SELECT @StartDate='6/21/2011'
      ,@EndDate='6/28/2011'
;with AllDates AS
(
    SELECT @StartDate AS DateOf, datepart(weekday,getdate()) AS WeekDayNumber
    UNION ALL
    SELECT DateOf+1, (WeekDayNumber+1) % 7
        FROM AllDates
    WHERE DateOf<@EndDate
)
SELECT COUNT(*) AS WeekDayCount FROM AllDates WHERE WeekDayNumber>0 AND WeekDayNumber<6
--I don't like using "BETWEEN", ">", ">=", "<", and "<=" are more explicit in defining end points

выдает тот же результат, что и исходный запрос.

1 голос
/ 21 июня 2011

Попробуйте

 DateDiff(day, @DtA, @DtB) - 2 * DateDiff(Week, @DtA, @DtB)

это может работать не совсем точно, но вы можете увидеть идею. Некоторые небольшие изменения будут работать.

0 голосов
/ 28 января 2016

Этот подход ограничен ~ 100 днями из-за рекурсии. Это работает для диапазонов дат, которые я проверял. Та же идея выше, убрал математику и упростил:

BEGIN
    SET DATEFIRST 1
    DECLARE @StartDate datetime
           ,@EndDate datetime
    SELECT @StartDate='12/16/2015'
          ,@EndDate='1/8/2016'
    ;with AllDates AS
    (
        SELECT @StartDate AS DateOf 
        UNION ALL
        SELECT DateOf+1 
            FROM AllDates
        WHERE DateOf<@EndDate
    )
    SELECT COUNT(*) AS WeekDayCount 
        FROM 
        AllDates 
    WHERE 
        datepart(weekday,DateOf) between 1 AND 5

    --SELECT DateOf [date], datepart(weekday,DateOf) [day] 
    --FROM 
    --  AllDates 
    --WHERE 
    --  datepart(weekday,DateOf) between 1 AND 5
END
0 голосов
/ 21 июня 2011
0 голосов
/ 21 июня 2011

Попробуйте следующее:

DECLARE @StartDate DATETIME
DECLARE @EndDate DATETIME
SET @StartDate = '2011/06/01'
SET @EndDate = '2011/06/31'

SELECT   
    (DATEDIFF(dd, @StartDate, @EndDate) + 1)  - 
    (DATEDIFF(wk, @StartDate, @EndDate) * 5)  -
    (
        CASE 
           WHEN DATENAME(dw, @StartDate) in 
               ('Sunday', 'Tuesday', 'Wednesday', 'Turesday', 'Saturday') 
           THEN 1 
           ELSE 0 
        END
    )  -
    (
        CASE 
           WHEN DATENAME(dw, @EndDate) in 
               ('Sunday', 'Tuesday', 'Wednesday', 'Turesday', 'Saturday') 
           THEN 1 
           ELSE 0 
        END
    )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...