Расчет рабочих дней в неделю - PullRequest
0 голосов
/ 28 мая 2018

Я хочу рассчитать количество рабочих дней в неделе для данного месяца.Мне написали этот запрос, который позволяет мне получить дни и даты, но я не могу разделить их на недели.

Вот запрос:

DECLARE @intEmployeeCode INT = 2309
DECLARE @StartDate datetime;
DECLARE @EndDate datetime;

DECLARE @Month int
DECLARE @Year int

SET @Month = month(getdate())
SET @Year = year(getdate())

SET @StartDate = (select DATEADD(month,month(getdate())-1,DATEADD(year,year(getdate())-1900,0)) ) /*First*/
SET @EndDate = (select DATEADD(day,-1,DATEADD(month,@Month,DATEADD(year,@Year-1900,0))) )/*Last*/


;WITH cte AS (
    SELECT 
    CAST(CAST (@StartDate AS NVARCHAR) AS date) AS myDate
    UNION ALL
    SELECT DATEADD(day,1,myDate) as myDate

    FROM cte
    WHERE DATEADD(day,1,myDate) <= CAST(CAST (@EndDate AS NVARCHAR) AS date))

SELECT myDate ,datename(dw,myDate) AS DayOfDate
FROM cte 
WHERE datename(dw,myDate) <> 'Sunday'
OPTION (MAXRECURSION 0);

Ожидаемый результат:

Week Number  Working Days
Week 1       5
Week 2       6
Week 3       6
Week 4       6
Week 5       4

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Попробуйте (комментарии в коде):

DECLARE @intEmployeeCode INT = 2309
DECLARE @StartDate date;
DECLARE @EndDate date;
--I changed your code a little, removed unnecessary variables
--below always returns first and last day of current month
SET @StartDate = DATEADD(dd, -(DATEPART(dd, GETDATE()) - 1), getdate())
SET @EndDate = DATEADD(dd, -1,DATEADD(mm, 1, @StartDate))

;WITH cte AS (
    SELECT @StartDate as myDate
    UNION ALL
    SELECT DATEADD(day,1,myDate) as myDate
    FROM cte
    WHERE DATEADD(day,1,myDate) <= CAST(CAST (@EndDate AS NVARCHAR) AS date)
)
--in subquery we generate additional column to group by week :)
--we also keep column indicating non-working day, Sunday
select weekGroup + 1 [WeekNumber],
       COUNT(*) [WorkingDays]
from (
    SELECT myDate,
           --here you specify non-working days, now they are sunday - 1 and saturday - 6
           case when DATEPART(dw, myDate) in (1,6) then 1 else 0 end isNonWorkingDay,
           sum(case DATEPART(dw, myDate) when 1 then 1 else 0 end) over (partition by (select null) order by myDate rows between unbounded preceding and current row) weekGroup
    FROM cte 
) [a]
where isNonWorkingDay = 0
group by weekGroup 
OPTION (MAXRECURSION 0);
0 голосов
/ 28 мая 2018

Должно быть возможно через DatePart, например:

DECLARE @intEmployeeCode INT = 2309
DECLARE @StartDate datetime;
DECLARE @EndDate datetime;

DECLARE @Month int
DECLARE @Year int

SET @Month = month(getdate()) + 2
SET @Year = year(getdate())

SET @StartDate = (select DATEADD(month,month(getdate())-1,DATEADD(year,year(getdate())-1900,0)) ) /*First*/
SET @EndDate = (select DATEADD(day,-1,DATEADD(month,@Month,DATEADD(year,@Year-1900,0))) )/*Last*/


;WITH cte AS (
    SELECT 
    CAST(CAST (@StartDate AS NVARCHAR) AS date) AS myDate
    UNION ALL
    SELECT DATEADD(day,1,myDate) as myDate

    FROM cte
    WHERE DATEADD(day,1,myDate) <= CAST(CAST (@EndDate AS NVARCHAR) AS date)
),
cteWeekwise AS(
SELECT myDate ,datename(dw,myDate) AS DayOfDate, DATEPART(YEAR, myDate) cwYear, DATEPART(MONTH, myDate) cwMonth, DATEPART(WEEK, myDate) cw, DENSE_RANK() OVER(PARTITION BY DATEPART(YEAR, myDate), DATEPART(MONTH, myDate) ORDER BY DATEPART(WEEK, myDate)) WeekIdx
FROM cte 
WHERE datename(dw,myDate) <> 'Sunday'
)
SELECT WeekIdx, cwYear, cwMonth, cw, COUNT(*) cnt
  FROM cteWeekwise
  --
  WHERE cwYear = 2018
    AND cwMonth = 5
    AND WeekIdx = 5
  --
  GROUP BY cwYear, cwMonth, cw, WeekIdx
  ORDER BY cwYear, cwMonth, cw
OPTION (MAXRECURSION 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...